@@ -33,7 +33,6 @@ println!("{}", key_pair.serialize_pem());
3333#![ cfg_attr( docsrs, feature( doc_cfg, doc_auto_cfg) ) ]
3434#![ warn( unreachable_pub) ]
3535
36- use std:: collections:: HashMap ;
3736use std:: fmt;
3837use std:: hash:: Hash ;
3938use std:: net:: IpAddr ;
@@ -299,8 +298,7 @@ See also the RFC 5280 sections on the [issuer](https://tools.ietf.org/html/rfc52
299298and [subject](https://tools.ietf.org/html/rfc5280#section-4.1.2.6) fields.
300299*/
301300pub struct DistinguishedName {
302- entries : HashMap < DnType , DnValue > ,
303- order : Vec < DnType > ,
301+ entries : Vec < ( DnType , DnValue ) > ,
304302}
305303
306304impl DistinguishedName {
@@ -309,20 +307,32 @@ impl DistinguishedName {
309307 Self :: default ( )
310308 }
311309 /// Obtains the attribute value for the given attribute type
312- pub fn get ( & self , ty : & DnType ) -> Option < & DnValue > {
313- self . entries . get ( ty)
310+ pub fn get ( & self , ty : & DnType ) -> Vec < & DnValue > {
311+ self . entries
312+ . iter ( )
313+ . filter_map ( |( dn_type, dn_value) | if ty == dn_type { Some ( dn_value) } else { None } )
314+ . collect ( )
314315 }
315316 /// Removes the attribute with the specified DnType
316317 ///
317318 /// Returns true when an actual removal happened, false
318319 /// when no attribute with the specified DnType was
319320 /// found.
320321 pub fn remove ( & mut self , ty : DnType ) -> bool {
321- let removed = self . entries . remove ( & ty) . is_some ( ) ;
322- if removed {
323- self . order . retain ( |ty_o| & ty != ty_o) ;
322+ let mut remove_indices = vec ! [ ] ;
323+ for ( index, ( dn_type, _dn_val) ) in self . entries . iter ( ) . enumerate ( ) {
324+ if dn_type == & ty {
325+ remove_indices. push ( index) ;
326+ }
327+ }
328+
329+ let is_remove_indices = !remove_indices. is_empty ( ) ;
330+
331+ for index in remove_indices {
332+ self . entries . remove ( index) ;
324333 }
325- removed
334+
335+ is_remove_indices
326336 }
327337 /// Inserts or updates an attribute that consists of type and name
328338 ///
@@ -331,21 +341,11 @@ impl DistinguishedName {
331341 /// let mut dn = DistinguishedName::new();
332342 /// dn.push(DnType::OrganizationName, "Crab widgits SE");
333343 /// dn.push(DnType::CommonName, DnValue::PrintableString("Master Cert".try_into().unwrap()));
334- /// assert_eq!(dn.get(&DnType::OrganizationName), Some(&DnValue::Utf8String("Crab widgits SE".to_string())));
335- /// assert_eq!(dn.get(&DnType::CommonName), Some(&DnValue::PrintableString("Master Cert".try_into().unwrap())));
344+ /// assert_eq!(dn.get(&DnType::OrganizationName).get(0) , Some(&DnValue::Utf8String("Crab widgits SE".to_string())).as_ref( ));
345+ /// assert_eq!(dn.get(&DnType::CommonName).get(0) , Some(&DnValue::PrintableString("Master Cert".try_into().unwrap())).as_ref( ));
336346 /// ```
337347 pub fn push ( & mut self , ty : DnType , s : impl Into < DnValue > ) {
338- if !self . entries . contains_key ( & ty) {
339- self . order . push ( ty. clone ( ) ) ;
340- }
341- self . entries . insert ( ty, s. into ( ) ) ;
342- }
343- /// Iterate over the entries
344- pub fn iter ( & self ) -> DistinguishedNameIterator < ' _ > {
345- DistinguishedNameIterator {
346- distinguished_name : self ,
347- iter : self . order . iter ( ) ,
348- }
348+ self . entries . push ( ( ty, s. into ( ) ) ) ;
349349 }
350350
351351 #[ cfg( feature = "x509-parser" ) ]
@@ -393,21 +393,15 @@ impl DistinguishedName {
393393 }
394394}
395395
396- /**
397- Iterator over [`DistinguishedName`] entries
398- */
399- pub struct DistinguishedNameIterator < ' a > {
400- distinguished_name : & ' a DistinguishedName ,
401- iter : std:: slice:: Iter < ' a , DnType > ,
402- }
403-
404- impl < ' a > Iterator for DistinguishedNameIterator < ' a > {
405- type Item = ( & ' a DnType , & ' a DnValue ) ;
396+ impl Iterator for DistinguishedName {
397+ type Item = ( DnType , DnValue ) ;
406398
407399 fn next ( & mut self ) -> Option < Self :: Item > {
408- self . iter
409- . next ( )
410- . and_then ( |ty| self . distinguished_name . entries . get ( ty) . map ( |v| ( ty, v) ) )
400+ self . entries . pop ( )
401+ }
402+
403+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
404+ self . entries . iter ( ) . size_hint ( )
411405 }
412406}
413407
@@ -568,9 +562,9 @@ fn write_dt_utc_or_generalized(writer: DERWriter, dt: OffsetDateTime) {
568562 }
569563}
570564
571- fn write_distinguished_name ( writer : DERWriter , dn : & DistinguishedName ) {
565+ fn write_distinguished_name ( writer : DERWriter , dn : DistinguishedName ) {
572566 writer. write_sequence ( |writer| {
573- for ( ty, content) in dn. iter ( ) {
567+ for ( ty, content) in dn. into_iter ( ) {
574568 writer. next ( ) . write_set ( |writer| {
575569 writer. next ( ) . write_sequence ( |writer| {
576570 writer. next ( ) . write_oid ( & ty. to_oid ( ) ) ;
@@ -596,7 +590,7 @@ fn write_distinguished_name(writer: DERWriter, dn: &DistinguishedName) {
596590 . write_tagged_implicit ( TAG_UNIVERSALSTRING , |writer| {
597591 writer. write_bytes ( s. as_bytes ( ) )
598592 } ) ,
599- DnValue :: Utf8String ( s) => writer. next ( ) . write_utf8_string ( s) ,
593+ DnValue :: Utf8String ( s) => writer. next ( ) . write_utf8_string ( s. as_str ( ) ) ,
600594 }
601595 } ) ;
602596 } ) ;
0 commit comments