Skip to main content

bitwarden_vault/cipher/blob/conversions/
drivers_license.rs

1use super::{DriversLicenseDataV1, DriversLicenseView};
2
3impl From<&DriversLicenseView> for DriversLicenseDataV1 {
4    fn from(src: &DriversLicenseView) -> Self {
5        Self {
6            first_name: src.first_name.clone(),
7            middle_name: src.middle_name.clone(),
8            last_name: src.last_name.clone(),
9            date_of_birth: src.date_of_birth.map(|d| d.to_string()),
10            license_number: src.license_number.clone(),
11            issuing_country: src.issuing_country.clone(),
12            issuing_state: src.issuing_state.clone(),
13            issue_date: src.issue_date.map(|d| d.to_string()),
14            expiration_date: src.expiration_date.map(|d| d.to_string()),
15            issuing_authority: src.issuing_authority.clone(),
16            license_class: src.license_class.clone(),
17        }
18    }
19}
20
21impl From<&DriversLicenseDataV1> for DriversLicenseView {
22    fn from(src: &DriversLicenseDataV1) -> Self {
23        Self {
24            first_name: src.first_name.clone(),
25            middle_name: src.middle_name.clone(),
26            last_name: src.last_name.clone(),
27            date_of_birth: src.date_of_birth.as_deref().and_then(|s| s.parse().ok()),
28            license_number: src.license_number.clone(),
29            issuing_country: src.issuing_country.clone(),
30            issuing_state: src.issuing_state.clone(),
31            issue_date: src.issue_date.as_deref().and_then(|s| s.parse().ok()),
32            expiration_date: src.expiration_date.as_deref().and_then(|s| s.parse().ok()),
33            issuing_authority: src.issuing_authority.clone(),
34            license_class: src.license_class.clone(),
35        }
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use super::super::{CipherBlobV1, test_support::*};
42    use crate::cipher::{cipher::CipherType, drivers_license::DriversLicenseView};
43
44    #[test]
45    fn test_drivers_license_cipher_round_trip() {
46        let (key_store, key_id) = create_test_key_store();
47        let mut ctx = key_store.context_mut();
48
49        let original = crate::CipherView {
50            name: "My Driver's License".to_string(),
51            notes: None,
52            r#type: CipherType::DriversLicense,
53            drivers_license: Some(DriversLicenseView {
54                first_name: Some("John".to_string()),
55                middle_name: Some("Michael".to_string()),
56                last_name: Some("Doe".to_string()),
57                date_of_birth: chrono::NaiveDate::from_ymd_opt(1985, 6, 15),
58                license_number: Some("DL-987654".to_string()),
59                issuing_country: Some("US".to_string()),
60                issuing_state: Some("NY".to_string()),
61                issue_date: chrono::NaiveDate::from_ymd_opt(2020, 1, 1),
62                expiration_date: chrono::NaiveDate::from_ymd_opt(2028, 1, 1),
63                issuing_authority: Some("NY DMV".to_string()),
64                license_class: Some("D".to_string()),
65            }),
66            ..create_shell_cipher_view(CipherType::DriversLicense)
67        };
68
69        let blob = CipherBlobV1::from_cipher_view(&original, &mut ctx, key_id).unwrap();
70        let mut restored = create_shell_cipher_view(CipherType::DriversLicense);
71        blob.apply_to_cipher_view(&mut restored, &mut ctx, key_id)
72            .unwrap();
73
74        assert_eq!(restored.name, "My Driver's License");
75        assert_eq!(restored.r#type, CipherType::DriversLicense);
76        let dl = restored.drivers_license.unwrap();
77        assert_eq!(dl.first_name, Some("John".to_string()));
78        assert_eq!(dl.license_number, Some("DL-987654".to_string()));
79        assert!(restored.login.is_none());
80    }
81}