@@ -33,6 +33,7 @@ println!("{}", signing_key.serialize_pem());
3333#![ warn( unreachable_pub) ]
3434
3535use std:: borrow:: Cow ;
36+ use std:: collections:: hash_map:: Entry ;
3637use std:: collections:: HashMap ;
3738use std:: fmt;
3839use std:: hash:: Hash ;
@@ -470,7 +471,7 @@ See also the RFC 5280 sections on the [issuer](https://tools.ietf.org/html/rfc52
470471and [subject](https://tools.ietf.org/html/rfc5280#section-4.1.2.6) fields.
471472*/
472473pub struct DistinguishedName {
473- entries : HashMap < DnType , DnValue > ,
474+ entries : HashMap < DnType , Vec < DnValue > > ,
474475 order : Vec < DnType > ,
475476}
476477
@@ -479,10 +480,17 @@ impl DistinguishedName {
479480 pub fn new ( ) -> Self {
480481 Self :: default ( )
481482 }
482- /// Obtains the attribute value for the given attribute type
483- pub fn get ( & self , ty : & DnType ) -> Option < & DnValue > {
484- self . entries . get ( ty)
483+
484+ /// Obtains the first attribute value for the given attribute type
485+ pub fn first ( & self , ty : & DnType ) -> Option < & DnValue > {
486+ self . entries . get ( ty) ?. first ( )
487+ }
488+
489+ /// Obtains all attribute values for the given attribute type
490+ pub fn get ( & self , ty : & DnType ) -> Option < & [ DnValue ] > {
491+ self . entries . get ( ty) . map ( |v| v. as_slice ( ) )
485492 }
493+
486494 /// Removes the attribute with the specified DnType
487495 ///
488496 /// Returns true when an actual removal happened, false
@@ -502,20 +510,24 @@ impl DistinguishedName {
502510 /// let mut dn = DistinguishedName::new();
503511 /// dn.push(DnType::OrganizationName, "Crab widgits SE");
504512 /// dn.push(DnType::CommonName, DnValue::PrintableString("Master Cert".try_into().unwrap()));
505- /// assert_eq!(dn.get (&DnType::OrganizationName), Some(&DnValue::Utf8String("Crab widgits SE".to_string())));
506- /// assert_eq!(dn.get (&DnType::CommonName), Some(&DnValue::PrintableString("Master Cert".try_into().unwrap())));
513+ /// assert_eq!(dn.first (&DnType::OrganizationName), Some(&DnValue::Utf8String("Crab widgits SE".to_string())));
514+ /// assert_eq!(dn.first (&DnType::CommonName), Some(&DnValue::PrintableString("Master Cert".try_into().unwrap())));
507515 /// ```
508516 pub fn push ( & mut self , ty : DnType , s : impl Into < DnValue > ) {
509- if !self . entries . contains_key ( & ty) {
510- self . order . push ( ty. clone ( ) ) ;
517+ match self . entries . entry ( ty. clone ( ) ) {
518+ Entry :: Occupied ( mut o) => o. get_mut ( ) . push ( s. into ( ) ) ,
519+ Entry :: Vacant ( v) => {
520+ v. insert ( Vec :: new ( ) ) . push ( s. into ( ) ) ;
521+ self . order . push ( ty) ;
522+ } ,
511523 }
512- self . entries . insert ( ty, s. into ( ) ) ;
513524 }
514525 /// Iterate over the entries
515526 pub fn iter ( & self ) -> DistinguishedNameIterator < ' _ > {
516527 DistinguishedNameIterator {
517528 distinguished_name : self ,
518529 iter : self . order . iter ( ) ,
530+ current : None ,
519531 }
520532 }
521533
@@ -571,15 +583,36 @@ Iterator over [`DistinguishedName`] entries
571583pub struct DistinguishedNameIterator < ' a > {
572584 distinguished_name : & ' a DistinguishedName ,
573585 iter : std:: slice:: Iter < ' a , DnType > ,
586+ current : Option < ( & ' a DnType , std:: slice:: Iter < ' a , DnValue > ) > ,
574587}
575588
576589impl < ' a > Iterator for DistinguishedNameIterator < ' a > {
577590 type Item = ( & ' a DnType , & ' a DnValue ) ;
578591
579592 fn next ( & mut self ) -> Option < Self :: Item > {
580- self . iter
581- . next ( )
582- . and_then ( |ty| self . distinguished_name . entries . get ( ty) . map ( |v| ( ty, v) ) )
593+ if let Some ( ( ty, values) ) = & mut self . current {
594+ match values. next ( ) {
595+ Some ( val) => return Some ( ( ty, val) ) ,
596+ None => self . current = None ,
597+ }
598+ }
599+
600+ while let Some ( ty) = self . iter . next ( ) {
601+ let Some ( values) = self . distinguished_name . entries . get ( ty) else {
602+ continue ;
603+ } ;
604+
605+ match values. as_slice ( ) {
606+ [ ] => continue ,
607+ [ first] => return Some ( ( ty, first) ) ,
608+ [ first, rest @ ..] => {
609+ self . current = Some ( ( ty, rest. iter ( ) ) ) ;
610+ return Some ( ( ty, first) ) ;
611+ }
612+ }
613+ }
614+
615+ None
583616 }
584617}
585618
0 commit comments