@@ -120,11 +120,11 @@ pub fn analyze(
120
120
}
121
121
x => {
122
122
if let Some ( en) = value. enum_ {
123
+ // plain enums do not need to recurse, can collect it here
123
124
let new_result = analyze_enum_properties ( & en, & next_stack, level, & schema) ?;
124
- results. extend ( new_result) ;
125
- // TODO: this should probably be done outside of the property recursion loop
125
+ results. push ( new_result) ;
126
126
} else {
127
- debug ! ( "not recursing into {} (not a container - {} )" , key, x)
127
+ debug ! ( "not recursing into {} ('{}' is not a container)" , key, x)
128
128
}
129
129
}
130
130
}
@@ -138,8 +138,7 @@ fn analyze_enum_properties(
138
138
stack : & str ,
139
139
level : u8 ,
140
140
schema : & JSONSchemaProps ,
141
- ) -> Result < Vec < OutputStruct > , anyhow:: Error > {
142
- let mut results = vec ! [ ] ;
141
+ ) -> Result < OutputStruct , anyhow:: Error > {
143
142
let mut members = vec ! [ ] ;
144
143
debug ! ( "analyzing enum {}" , serde_json:: to_string( & schema) . unwrap( ) ) ;
145
144
for en in items {
@@ -159,14 +158,13 @@ fn analyze_enum_properties(
159
158
docs : member_doc,
160
159
} )
161
160
}
162
- results . push ( OutputStruct {
161
+ Ok ( OutputStruct {
163
162
name : stack. to_string ( ) ,
164
163
members,
165
164
level,
166
165
docs : schema. description . clone ( ) ,
167
166
is_enum : true ,
168
- } ) ;
169
- Ok ( results)
167
+ } )
170
168
}
171
169
172
170
@@ -180,10 +178,11 @@ fn analyze_object_properties(
180
178
) -> Result < Vec < OutputStruct > , anyhow:: Error > {
181
179
let mut results = vec ! [ ] ;
182
180
let mut members = vec ! [ ] ;
183
- let mut is_enum = false ;
184
181
//debug!("analyzing object {}", serde_json::to_string(&schema).unwrap());
182
+ debug ! ( "analyze object props in {}" , stack) ;
185
183
let reqs = schema. required . clone ( ) . unwrap_or_default ( ) ;
186
184
for ( key, value) in props {
185
+ debug ! ( "analyze key {}" , key) ;
187
186
let value_type = value. type_ . clone ( ) . unwrap_or_default ( ) ;
188
187
let rust_type = match value_type. as_ref ( ) {
189
188
"object" => {
@@ -260,9 +259,8 @@ fn analyze_object_properties(
260
259
}
261
260
}
262
261
"string" => {
263
- debug ! ( "got string schema: {}" , serde_json:: to_string( & schema) . unwrap( ) ) ;
264
262
if let Some ( _en) = & value. enum_ {
265
- is_enum = true ;
263
+ debug ! ( "got enum string: {}" , serde_json :: to_string ( & schema ) . unwrap ( ) ) ;
266
264
format ! ( "{}{}" , stack, uppercase_first_letter( key) )
267
265
} else {
268
266
"String" . to_string ( )
@@ -308,17 +306,21 @@ fn analyze_object_properties(
308
306
members. push ( OutputMember {
309
307
type_ : format ! ( "Option<{}>" , rust_type) ,
310
308
name : key. to_string ( ) ,
311
- field_annot : Some ( r#"#[serde(default, skip_serializing_if = "Option::is_none")]"# . into ( ) ) ,
309
+ field_annot : Some ( r#"#[serde(default , skip_serializing_if = "Option::is_none")]"# . into ( ) ) ,
312
310
docs : member_doc,
313
311
} )
312
+ // TODO: must capture `default` key here instead of blindly using serde default
313
+ // this will require us storing default properties for the member in above loop
314
+ // This is complicated because serde default requires a default fn / impl Default
315
+ // probably better to do impl Default to avoid having to make custom fns
314
316
}
315
317
}
316
318
results. push ( OutputStruct {
317
319
name : stack. to_string ( ) ,
318
320
members,
319
321
level,
320
322
docs : schema. description . clone ( ) ,
321
- is_enum,
323
+ is_enum : false ,
322
324
} ) ;
323
325
Ok ( results)
324
326
}
@@ -569,7 +571,7 @@ type: object
569
571
"# ;
570
572
571
573
let schema: JSONSchemaProps = serde_yaml:: from_str ( schema_str) . unwrap ( ) ;
572
- env_logger:: init ( ) ;
574
+ // env_logger::init();
573
575
let mut structs = vec ! [ ] ;
574
576
analyze ( schema, "" , "MatchExpressions" , 0 , & mut structs) . unwrap ( ) ;
575
577
println ! ( "got {:?}" , structs) ;
@@ -596,7 +598,72 @@ type: object
596
598
}
597
599
598
600
#[ test]
599
- fn enum_nested ( ) {
601
+ fn enum_string_within_container ( ) {
602
+ let schema_str = r#"
603
+ description: Endpoint
604
+ properties:
605
+ relabelings:
606
+ items:
607
+ properties:
608
+ action:
609
+ default: replace
610
+ description: Action to perform based on regex matching.
611
+ Default is 'replace'
612
+ enum:
613
+ - replace
614
+ - keep
615
+ - drop
616
+ - hashmod
617
+ - labelmap
618
+ - labeldrop
619
+ - labelkeep
620
+ type: string
621
+ modulus:
622
+ format: int64
623
+ type: integer
624
+ type: object
625
+ type: array
626
+ type: object
627
+ "# ;
628
+
629
+ let schema: JSONSchemaProps = serde_yaml:: from_str ( schema_str) . unwrap ( ) ;
630
+ //env_logger::init();
631
+ let mut structs = vec ! [ ] ;
632
+ analyze ( schema, "" , "Endpoint" , 0 , & mut structs) . unwrap ( ) ;
633
+ println ! ( "got {:?}" , structs) ;
634
+ let root = & structs[ 0 ] ;
635
+ assert_eq ! ( root. name, "Endpoint" ) ;
636
+ assert_eq ! ( root. level, 0 ) ;
637
+ assert_eq ! ( root. is_enum, false ) ;
638
+ assert_eq ! ( & root. members[ 0 ] . name, "relabelings" ) ;
639
+ assert_eq ! ( & root. members[ 0 ] . type_, "Option<Vec<EndpointRelabelings>>" ) ;
640
+
641
+ let rel = & structs[ 1 ] ;
642
+ assert_eq ! ( rel. name, "EndpointRelabelings" ) ;
643
+ assert_eq ! ( rel. is_enum, false ) ;
644
+ assert_eq ! ( & rel. members[ 0 ] . name, "action" ) ;
645
+ assert_eq ! ( & rel. members[ 0 ] . type_, "Option<EndpointRelabelingsAction>" ) ;
646
+ // TODO: verify rel.members[0].field_annot uses correct default
647
+
648
+ // action enum member
649
+ let act = & structs[ 2 ] ;
650
+ assert_eq ! ( act. name, "EndpointRelabelingsAction" ) ;
651
+ assert_eq ! ( act. is_enum, true ) ;
652
+
653
+ // should have enum members:
654
+ assert_eq ! ( & act. members[ 0 ] . name, "replace" ) ;
655
+ assert_eq ! ( & act. members[ 0 ] . type_, "" ) ;
656
+ assert_eq ! ( & act. members[ 1 ] . name, "keep" ) ;
657
+ assert_eq ! ( & act. members[ 1 ] . type_, "" ) ;
658
+ assert_eq ! ( & act. members[ 2 ] . name, "drop" ) ;
659
+ assert_eq ! ( & act. members[ 2 ] . type_, "" ) ;
660
+ assert_eq ! ( & act. members[ 3 ] . name, "hashmod" ) ;
661
+ assert_eq ! ( & act. members[ 3 ] . type_, "" ) ;
662
+ }
663
+
664
+ #[ test]
665
+ #[ ignore] // oneof support not done
666
+ fn enum_oneof ( ) {
600
667
let schema_str = r#"
601
668
description: "Auto-generated derived type for ServerSpec via `CustomResource`"
602
669
properties:
@@ -645,7 +712,7 @@ type: object
645
712
type: object"# ;
646
713
647
714
let schema: JSONSchemaProps = serde_yaml:: from_str ( schema_str) . unwrap ( ) ;
648
- env_logger:: init ( ) ;
715
+ // env_logger::init();
649
716
let mut structs = vec ! [ ] ;
650
717
analyze ( schema, "" , "ServerSpec" , 0 , & mut structs) . unwrap ( ) ;
651
718
println ! ( "got {:?}" , structs) ;
@@ -718,7 +785,7 @@ type: object
718
785
type: object
719
786
"# ;
720
787
let schema: JSONSchemaProps = serde_yaml:: from_str ( schema_str) . unwrap ( ) ;
721
- env_logger:: init ( ) ;
788
+ // env_logger::init();
722
789
let mut structs = vec ! [ ] ;
723
790
analyze ( schema, "Endpoints" , "ServiceMonitor" , 0 , & mut structs) . unwrap ( ) ;
724
791
println ! ( "got {:?}" , structs) ;
0 commit comments