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}