1use credential_exchange_format::{
2 AddressCredential, Credential, CustomFieldsCredential, DriversLicenseCredential, EditableField,
3 EditableFieldString, EditableFieldValue, IdentityDocumentCredential, PassportCredential,
4 PersonNameCredential,
5};
6
7use crate::{
8 cxf::editable_field::{create_editable_field, create_field},
9 Field, Identity,
10};
11
12pub(super) fn address_to_identity(address: AddressCredential) -> (Identity, Vec<Field>) {
21 let identity = Identity {
22 address1: address.street_address.map(Into::into),
23 city: address.city.map(Into::into),
24 state: address.territory.map(Into::into),
25 postal_code: address.postal_code.map(Into::into),
26 country: address.country.map(Into::into),
27 phone: address.tel.map(Into::into),
28 ..Default::default()
29 };
30
31 (identity, vec![])
32}
33
34pub(super) fn passport_to_identity(passport: PassportCredential) -> (Identity, Vec<Field>) {
41 let (first_name, last_name) = split_name(&passport.full_name);
43
44 let identity = Identity {
45 first_name,
46 last_name,
47 ssn: passport.national_identification_number.map(Into::into),
49 passport_number: passport.passport_number.map(Into::into),
50 ..Default::default()
51 };
52
53 let custom_fields = [
55 passport
56 .issuing_country
57 .map(|issuing_country| create_field(&issuing_country, Some("Issuing Country"))),
58 passport
59 .nationality
60 .map(|nationality| create_field(&nationality, Some("Nationality"))),
61 passport
62 .birth_date
63 .map(|birth_date| create_field(&birth_date, Some("Birth Date"))),
64 passport
65 .birth_place
66 .map(|birth_place| create_field(&birth_place, Some("Birth Place"))),
67 passport.sex.map(|sex| create_field(&sex, Some("Sex"))),
68 passport
69 .issue_date
70 .map(|issue_date| create_field(&issue_date, Some("Issue Date"))),
71 passport
72 .expiry_date
73 .map(|expiry_date| create_field(&expiry_date, Some("Expiry Date"))),
74 passport
75 .issuing_authority
76 .map(|issuing_authority| create_field(&issuing_authority, Some("Issuing Authority"))),
77 passport
78 .passport_type
79 .map(|passport_type| create_field(&passport_type, Some("Passport Type"))),
80 ]
81 .into_iter()
82 .flatten()
83 .collect();
84
85 (identity, custom_fields)
86}
87
88pub(super) fn person_name_to_identity(person_name: PersonNameCredential) -> (Identity, Vec<Field>) {
98 let last_name = [
100 person_name.surname_prefix.as_ref(),
101 person_name.surname.as_ref(),
102 person_name.surname2.as_ref(),
103 ]
104 .into_iter()
105 .flatten()
106 .map(|field| field.value.0.clone())
107 .collect::<Vec<_>>()
108 .into_iter()
109 .reduce(|acc, part| format!("{acc} {part}"));
110
111 let identity = Identity {
112 title: person_name.title.map(Into::into),
113 first_name: person_name.given.map(Into::into),
114 middle_name: person_name.given2.map(Into::into),
115 last_name,
116 company: person_name.credentials.map(Into::into),
118 ..Default::default()
119 };
120
121 let custom_fields = [
123 person_name
124 .given_informal
125 .map(|given_informal| create_field(&given_informal, Some("Informal Given Name"))),
126 person_name
127 .generation
128 .map(|generation| create_field(&generation, Some("Generation"))),
129 ]
130 .into_iter()
131 .flatten()
132 .collect();
133
134 (identity, custom_fields)
135}
136
137pub(super) fn drivers_license_to_identity(
145 drivers_license: DriversLicenseCredential,
146) -> (Identity, Vec<Field>) {
147 let (first_name, last_name) = split_name(&drivers_license.full_name);
149
150 let identity = Identity {
151 first_name,
152 last_name,
153 state: drivers_license.territory.map(Into::into),
155 country: drivers_license.country.map(Into::into),
157 license_number: drivers_license.license_number.map(Into::into),
158 ..Default::default()
159 };
160
161 let custom_fields = [
163 drivers_license
164 .birth_date
165 .map(|birth_date| create_field(&birth_date, Some("Birth Date"))),
166 drivers_license
167 .issue_date
168 .map(|issue_date| create_field(&issue_date, Some("Issue Date"))),
169 drivers_license
170 .expiry_date
171 .map(|expiry_date| create_field(&expiry_date, Some("Expiry Date"))),
172 drivers_license
173 .issuing_authority
174 .map(|issuing_authority| create_field(&issuing_authority, Some("Issuing Authority"))),
175 drivers_license
176 .license_class
177 .map(|license_class| create_field(&license_class, Some("License Class"))),
178 ]
179 .into_iter()
180 .flatten()
181 .collect();
182
183 (identity, custom_fields)
184}
185
186pub(super) fn identity_document_to_identity(
195 identity_document: IdentityDocumentCredential,
196) -> (Identity, Vec<Field>) {
197 let (first_name, last_name) = split_name(&identity_document.full_name);
199
200 let identity = Identity {
201 first_name,
202 last_name,
203 ssn: identity_document.identification_number.map(Into::into),
205 passport_number: identity_document.document_number.map(Into::into),
207 ..Default::default()
208 };
209
210 let custom_fields = [
212 identity_document
213 .issuing_country
214 .map(|issuing_country| create_field(&issuing_country, Some("Issuing Country"))),
215 identity_document
216 .nationality
217 .map(|nationality| create_field(&nationality, Some("Nationality"))),
218 identity_document
219 .birth_date
220 .map(|birth_date| create_field(&birth_date, Some("Birth Date"))),
221 identity_document
222 .birth_place
223 .map(|birth_place| create_field(&birth_place, Some("Birth Place"))),
224 identity_document
225 .sex
226 .map(|sex| create_field(&sex, Some("Sex"))),
227 identity_document
228 .issue_date
229 .map(|issue_date| create_field(&issue_date, Some("Issue Date"))),
230 identity_document
231 .expiry_date
232 .map(|expiry_date| create_field(&expiry_date, Some("Expiry Date"))),
233 identity_document
234 .issuing_authority
235 .map(|issuing_authority| create_field(&issuing_authority, Some("Issuing Authority"))),
236 ]
237 .into_iter()
238 .flatten()
239 .collect();
240
241 (identity, custom_fields)
242}
243
244fn to_editable_field<T, U>(field: &Option<T>) -> Option<EditableField<U>>
245where
246 T: Clone + Into<EditableField<U>>,
247{
248 field.clone().map(|v| v.into())
249}
250
251fn split_name(
252 full_name: &Option<EditableField<EditableFieldString>>,
253) -> (Option<String>, Option<String>) {
254 full_name.as_ref().map_or((None, None), |name| {
255 let parts: Vec<&str> = name.value.0.split_whitespace().collect();
256 match parts.as_slice() {
257 [] => (None, None),
258 [first] => (Some(first.to_string()), None),
259 [first, rest @ ..] => (Some(first.to_string()), Some(rest.join(" "))),
260 }
261 })
262}
263
264impl From<&Identity> for PersonNameCredential {
265 fn from(identity: &Identity) -> Self {
266 PersonNameCredential {
267 title: to_editable_field(&identity.title),
268 given: to_editable_field(&identity.first_name),
269 given_informal: None,
270 given2: to_editable_field(&identity.middle_name),
271 surname_prefix: None,
272 surname: to_editable_field(&identity.last_name),
273 surname2: None,
274 credentials: to_editable_field(&identity.company),
275 generation: None,
276 }
278 }
279}
280
281impl From<&Identity> for AddressCredential {
282 fn from(identity: &Identity) -> Self {
283 let street_address = {
285 let address_lines: Vec<&str> =
286 [&identity.address1, &identity.address2, &identity.address3]
287 .into_iter()
288 .filter_map(|addr| addr.as_deref())
289 .collect();
290
291 if address_lines.is_empty() {
292 None
293 } else {
294 Some(address_lines.join("\n"))
295 }
296 };
297
298 AddressCredential {
299 street_address: street_address.map(|v| v.into()),
300 city: to_editable_field(&identity.city),
301 territory: to_editable_field(&identity.state),
302 country: to_editable_field(&identity.country),
303 tel: to_editable_field(&identity.phone),
304 postal_code: to_editable_field(&identity.postal_code),
305 }
306 }
307}
308
309impl From<&Identity> for PassportCredential {
310 fn from(identity: &Identity) -> Self {
311 let full_name = combine_name(
312 &identity.first_name,
313 &identity.middle_name,
314 &identity.last_name,
315 );
316
317 PassportCredential {
318 issuing_country: to_editable_field(&identity.country),
319 nationality: None,
320 full_name: full_name.map(|v| v.into()),
321 birth_date: None,
322 birth_place: None,
323 sex: None,
324 issue_date: None,
325 expiry_date: None,
326 issuing_authority: None,
327 passport_type: None,
328 passport_number: to_editable_field(&identity.passport_number),
329 national_identification_number: to_editable_field(&identity.ssn),
330 }
332 }
333}
334
335impl From<&Identity> for DriversLicenseCredential {
336 fn from(identity: &Identity) -> Self {
337 let full_name = combine_name(
338 &identity.first_name,
339 &identity.middle_name,
340 &identity.last_name,
341 );
342
343 DriversLicenseCredential {
344 full_name: full_name.map(|v| v.into()),
345 birth_date: None,
346 issue_date: None,
347 expiry_date: None,
348 issuing_authority: None,
349 territory: to_editable_field(&identity.state),
350 country: to_editable_field(&identity.country),
351 license_number: to_editable_field(&identity.license_number),
352 license_class: None,
353 }
355 }
356}
357
358impl From<&Identity> for IdentityDocumentCredential {
359 fn from(identity: &Identity) -> Self {
360 let full_name = combine_name(
361 &identity.first_name,
362 &identity.middle_name,
363 &identity.last_name,
364 );
365
366 IdentityDocumentCredential {
367 issuing_country: to_editable_field(&identity.country),
368 document_number: None,
369 identification_number: to_editable_field(&identity.ssn),
370 nationality: None,
371 full_name: full_name.map(|v| v.into()),
372 birth_date: None,
373 birth_place: None,
374 sex: None,
375 issue_date: None,
376 expiry_date: None,
377 issuing_authority: None,
378 }
380 }
381}
382
383impl From<Identity> for Vec<Credential> {
384 fn from(identity: Identity) -> Self {
385 let mut credentials = vec![];
386
387 let has_name_fields = identity.title.is_some()
389 || identity.first_name.is_some()
390 || identity.middle_name.is_some()
391 || identity.last_name.is_some()
392 || identity.company.is_some();
393
394 let has_address_fields = identity.address1.is_some()
396 || identity.city.is_some()
397 || identity.state.is_some()
398 || identity.country.is_some()
399 || identity.phone.is_some()
400 || identity.postal_code.is_some();
401
402 if has_name_fields {
404 credentials.push(Credential::PersonName(Box::new((&identity).into())));
405 }
406
407 if has_address_fields {
409 credentials.push(Credential::Address(Box::new((&identity).into())));
410 }
411
412 if identity.passport_number.is_some() {
414 credentials.push(Credential::Passport(Box::new((&identity).into())));
415 }
416
417 if identity.license_number.is_some() {
419 credentials.push(Credential::DriversLicense(Box::new((&identity).into())));
420 }
421
422 if identity.ssn.is_some() {
424 credentials.push(Credential::IdentityDocument(Box::new((&identity).into())));
425 }
426
427 let custom_fields: Vec<EditableFieldValue> = [
429 identity.email.as_ref().map(|email| {
430 EditableFieldValue::String(create_editable_field(
431 "Email".to_string(),
432 EditableFieldString(email.clone()),
433 ))
434 }),
435 identity.username.as_ref().map(|username| {
436 EditableFieldValue::String(create_editable_field(
437 "Username".to_string(),
438 EditableFieldString(username.clone()),
439 ))
440 }),
441 ]
442 .into_iter()
443 .flatten()
444 .collect();
445
446 if !custom_fields.is_empty() {
448 credentials.push(Credential::CustomFields(Box::new(CustomFieldsCredential {
449 id: None,
450 label: None,
451 fields: custom_fields,
452 extensions: vec![],
453 })));
454 }
455
456 credentials
457 }
458}
459
460pub(crate) fn combine_name(
461 first: &Option<String>,
462 middle: &Option<String>,
463 last: &Option<String>,
464) -> Option<String> {
465 let parts: Vec<&str> = [first.as_deref(), middle.as_deref(), last.as_deref()]
466 .into_iter()
467 .flatten()
468 .collect();
469
470 if parts.is_empty() {
471 None
472 } else {
473 Some(parts.join(" "))
474 }
475}
476
477#[cfg(test)]
478mod tests {
479 use credential_exchange_format::Credential;
480
481 use super::*;
482
483 #[test]
484 fn test_split_name_none() {
485 let full_name = None;
486 let (first, last) = split_name(&full_name);
487 assert_eq!(first, None);
488 assert_eq!(last, None);
489 }
490
491 #[test]
492 fn test_split_name_empty_string() {
493 let full_name = Some(EditableField {
494 value: EditableFieldString("".to_string()),
495 label: None,
496 id: None,
497 extensions: None,
498 });
499 let (first, last) = split_name(&full_name);
500 assert_eq!(first, None);
501 assert_eq!(last, None);
502 }
503
504 #[test]
505 fn test_split_name_whitespace_only() {
506 let full_name = Some(EditableField {
507 value: EditableFieldString(" \t\n ".to_string()),
508 label: None,
509 id: None,
510 extensions: None,
511 });
512 let (first, last) = split_name(&full_name);
513 assert_eq!(first, None);
514 assert_eq!(last, None);
515 }
516
517 #[test]
518 fn test_split_name_single_name() {
519 let full_name = Some(EditableField {
520 value: EditableFieldString("John".to_string()),
521 label: None,
522 id: None,
523 extensions: None,
524 });
525 let (first, last) = split_name(&full_name);
526 assert_eq!(first, Some("John".to_string()));
527 assert_eq!(last, None);
528 }
529
530 #[test]
531 fn test_split_name_single_name_with_whitespace() {
532 let full_name = Some(EditableField {
533 value: EditableFieldString(" John ".to_string()),
534 label: None,
535 id: None,
536 extensions: None,
537 });
538 let (first, last) = split_name(&full_name);
539 assert_eq!(first, Some("John".to_string()));
540 assert_eq!(last, None);
541 }
542
543 #[test]
544 fn test_split_name_first_last() {
545 let full_name = Some(EditableField {
546 value: EditableFieldString("John Doe".to_string()),
547 label: None,
548 id: None,
549 extensions: None,
550 });
551 let (first, last) = split_name(&full_name);
552 assert_eq!(first, Some("John".to_string()));
553 assert_eq!(last, Some("Doe".to_string()));
554 }
555
556 #[test]
557 fn test_split_name_first_middle_last() {
558 let full_name = Some(EditableField {
559 value: EditableFieldString("John Michael Doe".to_string()),
560 label: None,
561 id: None,
562 extensions: None,
563 });
564 let (first, last) = split_name(&full_name);
565 assert_eq!(first, Some("John".to_string()));
566 assert_eq!(last, Some("Michael Doe".to_string()));
567 }
568
569 #[test]
570 fn test_split_name_multiple_middle_names() {
571 let full_name = Some(EditableField {
572 value: EditableFieldString("John Michael Andrew Doe".to_string()),
573 label: None,
574 id: None,
575 extensions: None,
576 });
577 let (first, last) = split_name(&full_name);
578 assert_eq!(first, Some("John".to_string()));
579 assert_eq!(last, Some("Michael Andrew Doe".to_string()));
580 }
581
582 #[test]
583 fn test_split_name_complex_surname() {
584 let full_name = Some(EditableField {
585 value: EditableFieldString("Jane van der Berg".to_string()),
586 label: None,
587 id: None,
588 extensions: None,
589 });
590 let (first, last) = split_name(&full_name);
591 assert_eq!(first, Some("Jane".to_string()));
592 assert_eq!(last, Some("van der Berg".to_string()));
593 }
594
595 #[test]
596 fn test_split_name_hyphenated_surname() {
597 let full_name = Some(EditableField {
598 value: EditableFieldString("Mary Smith-Johnson".to_string()),
599 label: None,
600 id: None,
601 extensions: None,
602 });
603 let (first, last) = split_name(&full_name);
604 assert_eq!(first, Some("Mary".to_string()));
605 assert_eq!(last, Some("Smith-Johnson".to_string()));
606 }
607
608 #[test]
609 fn test_split_name_extra_whitespace() {
610 let full_name = Some(EditableField {
611 value: EditableFieldString(" John Michael Doe ".to_string()),
612 label: None,
613 id: None,
614 extensions: None,
615 });
616 let (first, last) = split_name(&full_name);
617 assert_eq!(first, Some("John".to_string()));
618 assert_eq!(last, Some("Michael Doe".to_string()));
619 }
620
621 #[test]
622 fn test_split_name_special_characters() {
623 let full_name = Some(EditableField {
624 value: EditableFieldString("José María González".to_string()),
625 label: None,
626 id: None,
627 extensions: None,
628 });
629 let (first, last) = split_name(&full_name);
630 assert_eq!(first, Some("José".to_string()));
631 assert_eq!(last, Some("María González".to_string()));
632 }
633
634 #[test]
635 fn test_split_name_single_character_names() {
636 let full_name = Some(EditableField {
637 value: EditableFieldString("A B C".to_string()),
638 label: None,
639 id: None,
640 extensions: None,
641 });
642 let (first, last) = split_name(&full_name);
643 assert_eq!(first, Some("A".to_string()));
644 assert_eq!(last, Some("B C".to_string()));
645 }
646
647 #[test]
648 fn test_identity_to_credentials() {
649 let identity = Identity {
650 title: Some("Dr.".to_string()),
651 first_name: Some("John".to_string()),
652 middle_name: Some("Michael".to_string()),
653 last_name: Some("Doe".to_string()),
654 address1: Some("123 Main St".to_string()),
655 address2: Some("Apt 456".to_string()),
656 address3: None,
657 city: Some("Anytown".to_string()),
658 state: Some("CA".to_string()),
659 postal_code: Some("12345".to_string()),
660 country: Some("US".to_string()),
661 company: Some("PhD".to_string()),
662 email: Some("[email protected]".to_string()),
663 phone: Some("+1234567890".to_string()),
664 ssn: Some("123-45-6789".to_string()),
665 username: Some("johndoe".to_string()),
666 passport_number: Some("P123456789".to_string()),
667 license_number: Some("DL123456".to_string()),
668 };
669
670 let credentials: Vec<Credential> = identity.into();
671
672 assert_eq!(credentials.len(), 6);
675
676 if let Credential::PersonName(person_name) = &credentials[0] {
678 assert_eq!(person_name.title.as_ref().unwrap().value.0, "Dr.");
679 assert_eq!(person_name.given.as_ref().unwrap().value.0, "John");
680 assert_eq!(person_name.given2.as_ref().unwrap().value.0, "Michael");
681 assert_eq!(person_name.surname.as_ref().unwrap().value.0, "Doe");
682 assert_eq!(person_name.credentials.as_ref().unwrap().value.0, "PhD");
683 } else {
684 panic!("Expected PersonName credential");
685 }
686
687 if let Credential::Address(address) = &credentials[1] {
689 assert_eq!(
690 address.street_address.as_ref().unwrap().value.0,
691 "123 Main St\nApt 456"
692 );
693 assert_eq!(address.city.as_ref().unwrap().value.0, "Anytown");
694 assert_eq!(address.territory.as_ref().unwrap().value.0, "CA");
695 assert_eq!(address.country.as_ref().unwrap().value.0, "US");
696 assert_eq!(address.tel.as_ref().unwrap().value.0, "+1234567890");
697 assert_eq!(address.postal_code.as_ref().unwrap().value.0, "12345");
698 } else {
699 panic!("Expected Address credential");
700 }
701
702 if let Credential::Passport(passport) = &credentials[2] {
704 assert_eq!(
705 passport.passport_number.as_ref().unwrap().value.0,
706 "P123456789"
707 );
708 assert_eq!(
709 passport.full_name.as_ref().unwrap().value.0,
710 "John Michael Doe"
711 );
712 assert_eq!(
713 passport
714 .national_identification_number
715 .as_ref()
716 .unwrap()
717 .value
718 .0,
719 "123-45-6789"
720 );
721 assert_eq!(passport.issuing_country.as_ref().unwrap().value.0, "US");
722 } else {
723 panic!("Expected Passport credential");
724 }
725
726 if let Credential::DriversLicense(license) = &credentials[3] {
728 assert_eq!(license.license_number.as_ref().unwrap().value.0, "DL123456");
729 assert_eq!(
730 license.full_name.as_ref().unwrap().value.0,
731 "John Michael Doe"
732 );
733 assert_eq!(license.territory.as_ref().unwrap().value.0, "CA");
734 assert_eq!(license.country.as_ref().unwrap().value.0, "US");
735 } else {
736 panic!("Expected DriversLicense credential");
737 }
738
739 if let Credential::IdentityDocument(identity_doc) = &credentials[4] {
741 assert_eq!(
742 identity_doc.identification_number.as_ref().unwrap().value.0,
743 "123-45-6789"
744 );
745 assert_eq!(
746 identity_doc.full_name.as_ref().unwrap().value.0,
747 "John Michael Doe"
748 );
749 } else {
750 panic!("Expected IdentityDocument credential");
751 }
752
753 if let Credential::CustomFields(custom_fields) = &credentials[5] {
755 assert_eq!(custom_fields.fields.len(), 2); let email_field = &custom_fields.fields[0];
759 if let EditableFieldValue::String(email_field) = email_field {
760 assert_eq!(email_field.label.as_ref().unwrap(), "Email");
761 assert_eq!(email_field.value.0, "[email protected]");
762 } else {
763 panic!("Expected email field to be of type String");
764 }
765
766 let username_field = &custom_fields.fields[1];
768 if let EditableFieldValue::String(username_field) = username_field {
769 assert_eq!(username_field.label.as_ref().unwrap(), "Username");
770 assert_eq!(username_field.value.0, "johndoe");
771 } else {
772 panic!("Expected username field to be of type String");
773 }
774 } else {
775 panic!("Expected CustomFields credential");
776 }
777 }
778
779 #[test]
780 fn test_identity_minimal_fields() {
781 let identity = Identity {
782 first_name: Some("Jane".to_string()),
783 last_name: Some("Smith".to_string()),
784 ..Default::default()
785 };
786
787 let credentials: Vec<Credential> = identity.into();
788
789 assert_eq!(credentials.len(), 1);
791
792 if let Credential::PersonName(person_name) = &credentials[0] {
793 assert_eq!(person_name.given.as_ref().unwrap().value.0, "Jane");
794 assert_eq!(person_name.surname.as_ref().unwrap().value.0, "Smith");
795 assert!(person_name.title.is_none());
796 assert!(person_name.given2.is_none());
797 } else {
798 panic!("Expected PersonName credential");
799 }
800 }
801
802 #[test]
803 fn test_identity_license_only() {
804 let identity = Identity {
805 first_name: Some("Alice".to_string()),
806 license_number: Some("LIC123456".to_string()),
807 state: Some("NY".to_string()),
808 ..Default::default()
809 };
810
811 let credentials: Vec<Credential> = identity.into();
812
813 assert_eq!(credentials.len(), 3);
815
816 if let Credential::PersonName(person_name) = &credentials[0] {
818 assert_eq!(person_name.given.as_ref().unwrap().value.0, "Alice");
819 } else {
820 panic!("Expected PersonName credential");
821 }
822
823 if let Credential::Address(address) = &credentials[1] {
825 assert_eq!(address.territory.as_ref().unwrap().value.0, "NY");
826 } else {
827 panic!("Expected Address credential");
828 }
829
830 if let Credential::DriversLicense(license) = &credentials[2] {
832 assert_eq!(
833 license.license_number.as_ref().unwrap().value.0,
834 "LIC123456"
835 );
836 assert_eq!(license.full_name.as_ref().unwrap().value.0, "Alice");
837 assert_eq!(license.territory.as_ref().unwrap().value.0, "NY");
838 } else {
839 panic!("Expected DriversLicense credential");
840 }
841 }
842
843 #[test]
844 fn test_identity_ssn_only() {
845 let identity = Identity {
846 first_name: Some("Bob".to_string()),
847 ssn: Some("987-65-4321".to_string()),
848 ..Default::default()
849 };
850
851 let credentials: Vec<Credential> = identity.into();
852
853 assert_eq!(credentials.len(), 2);
855
856 if let Credential::IdentityDocument(identity_doc) = &credentials[1] {
857 assert_eq!(
858 identity_doc.identification_number.as_ref().unwrap().value.0,
859 "987-65-4321"
860 );
861 assert_eq!(identity_doc.full_name.as_ref().unwrap().value.0, "Bob");
862 } else {
863 panic!("Expected IdentityDocument credential");
864 }
865 }
866
867 #[test]
868 fn test_identity_empty() {
869 let identity = Identity::default();
870
871 let credentials: Vec<Credential> = identity.into();
872
873 assert_eq!(credentials.len(), 0);
875 }
876
877 #[test]
878 fn test_combine_name_helper() {
879 assert_eq!(
880 combine_name(
881 &Some("John".to_string()),
882 &Some("Michael".to_string()),
883 &Some("Doe".to_string())
884 ),
885 Some("John Michael Doe".to_string())
886 );
887
888 assert_eq!(
889 combine_name(&Some("Jane".to_string()), &None, &Some("Smith".to_string())),
890 Some("Jane Smith".to_string())
891 );
892
893 assert_eq!(
894 combine_name(&Some("Bob".to_string()), &None, &None),
895 Some("Bob".to_string())
896 );
897
898 assert_eq!(combine_name(&None, &None, &None), None);
899 }
900}