bitwarden_vault/cipher/
linked_id.rs

1use bitwarden_core::MissingFieldError;
2use serde::{Deserialize, Serialize};
3use serde_repr::{Deserialize_repr, Serialize_repr};
4#[cfg(feature = "wasm")]
5use tsify_next::Tsify;
6#[cfg(feature = "wasm")]
7use wasm_bindgen::prelude::wasm_bindgen;
8
9#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Debug)]
10#[serde(untagged)]
11#[cfg_attr(feature = "wasm", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
12pub enum LinkedIdType {
13    Login(LoginLinkedIdType),
14    Card(CardLinkedIdType),
15    Identity(IdentityLinkedIdType),
16}
17
18#[cfg(feature = "uniffi")]
19use crate::UniffiCustomTypeConverter;
20#[cfg(feature = "uniffi")]
21uniffi::custom_type!(LinkedIdType, u32);
22#[cfg(feature = "uniffi")]
23impl UniffiCustomTypeConverter for LinkedIdType {
24    type Builtin = u32;
25
26    fn into_custom(val: Self::Builtin) -> uniffi::Result<Self> {
27        let val = serde_json::Value::Number(val.into());
28        Ok(serde_json::from_value(val)?)
29    }
30
31    fn from_custom(obj: Self) -> Self::Builtin {
32        obj.into()
33    }
34}
35
36impl From<LinkedIdType> for u32 {
37    fn from(v: LinkedIdType) -> Self {
38        serde_json::to_value(v)
39            .expect("LinkedIdType should be serializable")
40            .as_u64()
41            .expect("Not a numeric enum value") as u32
42    }
43}
44
45#[derive(Clone, Copy, PartialEq, Eq, Serialize_repr, Deserialize_repr, Debug)]
46#[repr(u16)]
47#[cfg_attr(feature = "wasm", wasm_bindgen)]
48pub enum LoginLinkedIdType {
49    Username = 100,
50    Password = 101,
51}
52
53#[derive(Clone, Copy, PartialEq, Eq, Serialize_repr, Deserialize_repr, Debug)]
54#[repr(u16)]
55#[cfg_attr(feature = "wasm", wasm_bindgen)]
56pub enum CardLinkedIdType {
57    CardholderName = 300,
58    ExpMonth = 301,
59    ExpYear = 302,
60    Code = 303,
61    Brand = 304,
62    Number = 305,
63}
64
65#[derive(Clone, Copy, PartialEq, Eq, Serialize_repr, Deserialize_repr, Debug)]
66#[repr(u16)]
67#[cfg_attr(feature = "wasm", wasm_bindgen)]
68pub enum IdentityLinkedIdType {
69    Title = 400,
70    MiddleName = 401,
71    Address1 = 402,
72    Address2 = 403,
73    Address3 = 404,
74    City = 405,
75    State = 406,
76    PostalCode = 407,
77    Country = 408,
78    Company = 409,
79    Email = 410,
80    Phone = 411,
81    Ssn = 412,
82    Username = 413,
83    PassportNumber = 414,
84    LicenseNumber = 415,
85    FirstName = 416,
86    LastName = 417,
87    FullName = 418,
88}
89
90impl TryFrom<u32> for LinkedIdType {
91    type Error = MissingFieldError;
92
93    fn try_from(value: u32) -> Result<Self, Self::Error> {
94        match value {
95            100 => Ok(LinkedIdType::Login(LoginLinkedIdType::Username)),
96            101 => Ok(LinkedIdType::Login(LoginLinkedIdType::Password)),
97            300 => Ok(LinkedIdType::Card(CardLinkedIdType::CardholderName)),
98            301 => Ok(LinkedIdType::Card(CardLinkedIdType::ExpMonth)),
99            302 => Ok(LinkedIdType::Card(CardLinkedIdType::ExpYear)),
100            303 => Ok(LinkedIdType::Card(CardLinkedIdType::Code)),
101            304 => Ok(LinkedIdType::Card(CardLinkedIdType::Brand)),
102            305 => Ok(LinkedIdType::Card(CardLinkedIdType::Number)),
103            400 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::Title)),
104            401 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::MiddleName)),
105            402 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::Address1)),
106            403 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::Address2)),
107            404 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::Address3)),
108            405 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::City)),
109            406 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::State)),
110            407 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::PostalCode)),
111            408 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::Country)),
112            409 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::Company)),
113            410 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::Email)),
114            411 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::Phone)),
115            412 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::Ssn)),
116            413 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::Username)),
117            414 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::PassportNumber)),
118            415 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::LicenseNumber)),
119            416 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::FirstName)),
120            417 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::LastName)),
121            418 => Ok(LinkedIdType::Identity(IdentityLinkedIdType::FullName)),
122            _ => Err(MissingFieldError("LinkedIdType")),
123        }
124    }
125}
126
127#[cfg(test)]
128mod tests {
129
130    #[test]
131    fn test_linked_id_serialization() {
132        use super::{LinkedIdType, LoginLinkedIdType};
133
134        #[derive(serde::Serialize, serde::Deserialize)]
135        struct Test {
136            id: LinkedIdType,
137        }
138
139        let json = "{\"id\":100}";
140        let val = serde_json::from_str::<Test>(json).unwrap();
141
142        assert_eq!(val.id, LinkedIdType::Login(LoginLinkedIdType::Username));
143
144        let serialized = serde_json::to_string(&val).unwrap();
145        assert_eq!(serialized, json);
146    }
147
148    #[cfg(feature = "uniffi")]
149    #[test]
150    fn test_linked_id_serialization_uniffi() {
151        use super::{CardLinkedIdType, LinkedIdType, LoginLinkedIdType};
152
153        assert_eq!(
154            100,
155            crate::UniffiCustomTypeConverter::from_custom(LinkedIdType::Login(
156                LoginLinkedIdType::Username
157            ))
158        );
159        assert_eq!(
160            303,
161            crate::UniffiCustomTypeConverter::from_custom(LinkedIdType::Card(
162                CardLinkedIdType::Code
163            ))
164        );
165
166        assert_eq!(
167            LinkedIdType::Login(LoginLinkedIdType::Username),
168            crate::UniffiCustomTypeConverter::into_custom(100).unwrap()
169        );
170        assert_eq!(
171            LinkedIdType::Card(CardLinkedIdType::Code),
172            crate::UniffiCustomTypeConverter::into_custom(303).unwrap()
173        );
174    }
175}