@@ -67,7 +67,7 @@ impl ToplevelDefinition {
6767 | ToplevelDefinition :: Type ( ToplevelTypeDefinition {
6868 ty : ASN1Type :: SetOf ( s) ,
6969 ..
70- } ) => s. element_type . constraints ( ) . map_or ( false , |constraints| {
70+ } ) => s. element_type . constraints ( ) . is_some_and ( |constraints| {
7171 constraints
7272 . iter ( )
7373 . any ( |c| matches ! ( c, Constraint :: Parameter ( _) ) )
@@ -87,15 +87,14 @@ impl ToplevelDefinition {
8787 }
8888 match & t. ty {
8989 ASN1Type :: Enumerated ( e) => {
90- return e
91- . members
92- . iter ( )
93- . find_map ( |m| ( & m. name == identifier) . then ( || ASN1Value :: Integer ( m. index ) ) )
90+ return e. members . iter ( ) . find_map ( |m| {
91+ ( & m. name == identifier) . then_some ( ASN1Value :: Integer ( m. index ) )
92+ } )
9493 }
9594 ASN1Type :: Integer ( i) => {
9695 return i. distinguished_values . as_ref ( ) . and_then ( |dv| {
9796 dv. iter ( ) . find_map ( |d| {
98- ( & d. name == identifier) . then ( || ASN1Value :: Integer ( d. value ) )
97+ ( & d. name == identifier) . then_some ( ASN1Value :: Integer ( d. value ) )
9998 } )
10099 } )
101100 }
@@ -117,9 +116,16 @@ impl ToplevelDefinition {
117116
118117 /// Checks if at any depth down the arbitrarily nested `self`, an elsewhere declared type with the name `name` exists.
119118 /// Sequence Ofs and Set Ofs break the recursion tree, because they use heap-based data structures.
120- pub fn recurses ( & self , name : & str , tlds : & BTreeMap < String , ToplevelDefinition > ) -> bool {
119+ pub fn recurses (
120+ & self ,
121+ name : & str ,
122+ tlds : & BTreeMap < String , ToplevelDefinition > ,
123+ reference_graph : Vec < & str > ,
124+ ) -> bool {
121125 match self {
122- ToplevelDefinition :: Type ( ToplevelTypeDefinition { ty, .. } ) => ty. recurses ( name, tlds) ,
126+ ToplevelDefinition :: Type ( ToplevelTypeDefinition { ty, .. } ) => {
127+ ty. recurses ( name, tlds, reference_graph)
128+ }
123129 _ => false , // TODO: Check recursion for values and information objects
124130 }
125131 }
@@ -176,7 +182,7 @@ impl ToplevelDefinition {
176182 /// will be represented in the generated rust bindings.
177183 /// ### Params
178184 /// * `tlds` - vector of other top-level declarations that will be searched as the method resolves a reference
179- /// returns `true` if the reference was resolved successfully.
185+ /// returns `true` if the reference was resolved successfully.
180186 pub fn link_constraint_reference (
181187 & mut self ,
182188 tlds : & BTreeMap < String , ToplevelDefinition > ,
@@ -276,16 +282,10 @@ impl ASN1Type {
276282 pub fn has_choice_selection_type ( & self ) -> bool {
277283 match self {
278284 ASN1Type :: ChoiceSelectionType ( _) => true ,
279- ASN1Type :: Sequence ( s) | ASN1Type :: Set ( s) => s
280- . members
281- . iter ( )
282- . map ( |m| m. ty . has_choice_selection_type ( ) )
283- . any ( |b| b) ,
284- ASN1Type :: Choice ( c) => c
285- . options
286- . iter ( )
287- . map ( |o| o. ty . has_choice_selection_type ( ) )
288- . any ( |b| b) ,
285+ ASN1Type :: Sequence ( s) | ASN1Type :: Set ( s) => {
286+ s. members . iter ( ) . any ( |m| m. ty . has_choice_selection_type ( ) )
287+ }
288+ ASN1Type :: Choice ( c) => c. options . iter ( ) . any ( |o| o. ty . has_choice_selection_type ( ) ) ,
289289 ASN1Type :: SequenceOf ( s) | ASN1Type :: SetOf ( s) => {
290290 s. element_type . has_choice_selection_type ( )
291291 }
@@ -566,24 +566,33 @@ impl ASN1Type {
566566
567567 /// Checks if at any depth down the arbitrarily nested `self`, an elsewhere declared type with the name `name` exists.
568568 /// Sequence Ofs and Set Ofs break the recursion tree, because they use heap-based data structures.
569- pub fn recurses ( & self , name : & str , tlds : & BTreeMap < String , ToplevelDefinition > ) -> bool {
569+ /// The `reference_graph` serves to detect circular references in the recursion tree. If a circular reference is detected,
570+ /// recursion detection is stopped. The circular reference will be marked recursive once the respective type is captured mutably in `mark_recursive`.
571+ pub fn recurses (
572+ & self ,
573+ name : & str ,
574+ tlds : & BTreeMap < String , ToplevelDefinition > ,
575+ mut reference_graph : Vec < & str > ,
576+ ) -> bool {
570577 match self {
571578 ASN1Type :: ElsewhereDeclaredType ( DeclarationElsewhere { identifier, .. } ) => {
572- identifier == name
573- || tlds
574- . get ( identifier)
575- . is_some_and ( |tld| tld. recurses ( name, tlds) )
579+ !reference_graph. contains ( & identifier. as_str ( ) )
580+ && ( identifier == name
581+ || tlds. get ( identifier) . is_some_and ( |tld| {
582+ reference_graph. push ( identifier) ;
583+ tld. recurses ( name, tlds, reference_graph)
584+ } ) )
576585 }
577586 ASN1Type :: Choice ( c) => c. options . iter ( ) . any ( |opt|
578587 // if an option is already marked recursive,
579588 // it will be boxed and constitute a recursion
580589 // boundary between `self` and the option type
581- !opt. is_recursive && opt. ty . recurses ( name, tlds) ) ,
590+ !opt. is_recursive && opt. ty . recurses ( name, tlds, reference_graph . clone ( ) ) ) ,
582591 ASN1Type :: Sequence ( s) | ASN1Type :: Set ( s) => s. members . iter ( ) . any ( |m|
583592 // if a member is already marked recursive,
584593 // it will be boxed and thus constitutes a recursion
585594 // boundary between `self` and the member type
586- !m. is_recursive && m. ty . recurses ( name, tlds) ) ,
595+ !m. is_recursive && m. ty . recurses ( name, tlds, reference_graph . clone ( ) ) ) ,
587596 _ => false ,
588597 }
589598 }
@@ -598,7 +607,7 @@ impl ASN1Type {
598607 ASN1Type :: Choice ( choice) => {
599608 let mut children = Vec :: new ( ) ;
600609 for option in & mut choice. options {
601- option. is_recursive = option. ty . recurses ( name, tlds) ;
610+ option. is_recursive = option. ty . recurses ( name, tlds, Vec :: new ( ) ) ;
602611 let opt_ty_name = option. ty . as_str ( ) . into_owned ( ) ;
603612 let mut opt_children = option. ty . mark_recursive ( & opt_ty_name, tlds) ?;
604613 if opt_children. iter ( ) . any ( |id : & Cow < ' _ , str > | id == name) {
@@ -612,7 +621,7 @@ impl ASN1Type {
612621 ASN1Type :: Set ( s) | ASN1Type :: Sequence ( s) => {
613622 let mut children = Vec :: new ( ) ;
614623 for member in & mut s. members {
615- member. is_recursive = member. ty . recurses ( name, tlds) ;
624+ member. is_recursive = member. ty . recurses ( name, tlds, Vec :: new ( ) ) ;
616625 let mem_ty_name = member. ty . as_str ( ) . into_owned ( ) ;
617626 let mut mem_children = member. ty . mark_recursive ( & mem_ty_name, tlds) ?;
618627 if mem_children. iter ( ) . any ( |id : & Cow < ' _ , str > | id == name) {
@@ -776,7 +785,7 @@ impl ASN1Type {
776785 m. ty . contains_constraint_reference ( )
777786 || m. default_value
778787 . as_ref ( )
779- . map_or ( false , |d| d. is_elsewhere_declared ( ) )
788+ . is_some_and ( |d| d. is_elsewhere_declared ( ) )
780789 || m. constraints . iter ( ) . any ( |c| c. has_cross_reference ( ) )
781790 } )
782791 }
0 commit comments