bitwarden_vault/cipher/blob/conversions/
passport.rs1use super::{PassportDataV1, PassportView};
2
3impl From<&PassportView> for PassportDataV1 {
4 fn from(src: &PassportView) -> Self {
5 Self {
6 surname: src.surname.clone(),
7 given_name: src.given_name.clone(),
8 date_of_birth: src.date_of_birth.map(|d| d.to_string()),
9 sex: src.sex.clone(),
10 birth_place: src.birth_place.clone(),
11 nationality: src.nationality.clone(),
12 issuing_country: src.issuing_country.clone(),
13 passport_number: src.passport_number.clone(),
14 passport_type: src.passport_type.clone(),
15 national_identification_number: src.national_identification_number.clone(),
16 issuing_authority: src.issuing_authority.clone(),
17 issue_date: src.issue_date.map(|d| d.to_string()),
18 expiration_date: src.expiration_date.map(|d| d.to_string()),
19 }
20 }
21}
22
23impl From<&PassportDataV1> for PassportView {
24 fn from(src: &PassportDataV1) -> Self {
25 Self {
26 surname: src.surname.clone(),
27 given_name: src.given_name.clone(),
28 date_of_birth: src.date_of_birth.as_deref().and_then(|s| s.parse().ok()),
29 sex: src.sex.clone(),
30 birth_place: src.birth_place.clone(),
31 nationality: src.nationality.clone(),
32 issuing_country: src.issuing_country.clone(),
33 passport_number: src.passport_number.clone(),
34 passport_type: src.passport_type.clone(),
35 national_identification_number: src.national_identification_number.clone(),
36 issuing_authority: src.issuing_authority.clone(),
37 issue_date: src.issue_date.as_deref().and_then(|s| s.parse().ok()),
38 expiration_date: src.expiration_date.as_deref().and_then(|s| s.parse().ok()),
39 }
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::super::{CipherBlobV1, test_support::*};
46 use crate::cipher::{cipher::CipherType, passport::PassportView};
47
48 #[test]
49 fn test_passport_cipher_round_trip() {
50 let (key_store, key_id) = create_test_key_store();
51 let mut ctx = key_store.context_mut();
52
53 let original = crate::CipherView {
54 name: "My Passport".to_string(),
55 notes: None,
56 r#type: CipherType::Passport,
57 passport: Some(PassportView {
58 surname: Some("Doe".to_string()),
59 given_name: Some("Jane".to_string()),
60 date_of_birth: chrono::NaiveDate::from_ymd_opt(1990, 1, 1),
61 sex: Some("F".to_string()),
62 birth_place: Some("New York".to_string()),
63 nationality: Some("American".to_string()),
64 issuing_country: Some("US".to_string()),
65 passport_number: Some("P12345678".to_string()),
66 passport_type: Some("P".to_string()),
67 national_identification_number: Some("123-45-6789".to_string()),
68 issuing_authority: Some("US State Department".to_string()),
69 issue_date: chrono::NaiveDate::from_ymd_opt(2020, 1, 1),
70 expiration_date: chrono::NaiveDate::from_ymd_opt(2030, 1, 1),
71 }),
72 ..create_shell_cipher_view(CipherType::Passport)
73 };
74
75 let blob = CipherBlobV1::from_cipher_view(&original, &mut ctx, key_id).unwrap();
76 let mut restored = create_shell_cipher_view(CipherType::Passport);
77 blob.apply_to_cipher_view(&mut restored, &mut ctx, key_id)
78 .unwrap();
79
80 assert_eq!(restored.name, "My Passport");
81 assert_eq!(restored.r#type, CipherType::Passport);
82 let passport = restored.passport.unwrap();
83 assert_eq!(passport.surname, Some("Doe".to_string()));
84 assert_eq!(passport.passport_number, Some("P12345678".to_string()));
85 assert!(restored.login.is_none());
86 }
87}