Skip to content

Commit 4507db3

Browse files
committed
make simple enum case work
Signed-off-by: clux <[email protected]>
1 parent 3c9f95a commit 4507db3

File tree

2 files changed

+92
-22
lines changed

2 files changed

+92
-22
lines changed

src/analyzer.rs

Lines changed: 91 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
use crate::{OutputMember, OutputStruct};
33
use anyhow::{bail, Result};
44
use k8s_openapi::apiextensions_apiserver::pkg::apis::apiextensions::v1::{
5-
JSONSchemaProps, JSONSchemaPropsOrArray, JSONSchemaPropsOrBool,
5+
JSONSchemaProps, JSONSchemaPropsOrArray, JSONSchemaPropsOrBool, JSON,
66
};
77
use std::collections::{BTreeMap, HashMap};
88

@@ -118,12 +118,58 @@ pub fn analyze(
118118
debug!("not recursing into unknown empty type {}", key)
119119
}
120120
}
121-
x => debug!("not recursing into {} (not a container - {})", key, x),
121+
x => {
122+
if let Some(en) = value.enum_ {
123+
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
126+
} else {
127+
debug!("not recursing into {} (not a container - {})", key, x)
128+
}
129+
}
122130
}
123131
}
124132
Ok(())
125133
}
126134

135+
// helper to figure out what output enums and embedded members are contained in the current object schema
136+
fn analyze_enum_properties(
137+
items: &Vec<JSON>,
138+
stack: &str,
139+
level: u8,
140+
schema: &JSONSchemaProps,
141+
) -> Result<Vec<OutputStruct>, anyhow::Error> {
142+
let mut results = vec![];
143+
let mut members = vec![];
144+
debug!("analyzing enum {}", serde_json::to_string(&schema).unwrap());
145+
for en in items {
146+
//debug!("got enum {:?}", en);
147+
// TODO: do we need to verify enum elements? only in oneOf only right?
148+
let (name, rust_type) = match &en.0 {
149+
serde_json::Value::String(name) => (name, "".to_string()),
150+
_ => bail!("not handling non-string enum"),
151+
};
152+
// Create member and wrap types correctly
153+
let member_doc = None;
154+
debug!("with enum member {} of type {}", name, rust_type);
155+
members.push(OutputMember {
156+
type_: rust_type,
157+
name: name.to_string(),
158+
field_annot: None,
159+
docs: member_doc,
160+
})
161+
}
162+
results.push(OutputStruct {
163+
name: stack.to_string(),
164+
members,
165+
level,
166+
docs: schema.description.clone(),
167+
is_enum: true,
168+
});
169+
Ok(results)
170+
}
171+
172+
127173
// helper to figure out what output structs (returned) and embedded members are contained in the current object schema
128174
fn analyze_object_properties(
129175
props: &BTreeMap<String, JSONSchemaProps>,
@@ -134,6 +180,8 @@ fn analyze_object_properties(
134180
) -> Result<Vec<OutputStruct>, anyhow::Error> {
135181
let mut results = vec![];
136182
let mut members = vec![];
183+
let mut is_enum = false;
184+
//debug!("analyzing object {}", serde_json::to_string(&schema).unwrap());
137185
let reqs = schema.required.clone().unwrap_or_default();
138186
for (key, value) in props {
139187
let value_type = value.type_.clone().unwrap_or_default();
@@ -211,7 +259,15 @@ fn analyze_object_properties(
211259
format!("{}{}", stack, uppercase_first_letter(key))
212260
}
213261
}
214-
"string" => "String".to_string(),
262+
"string" => {
263+
debug!("got string schema: {}", serde_json::to_string(&schema).unwrap());
264+
if let Some(_en) = &value.enum_ {
265+
is_enum = true;
266+
format!("{}{}", stack, uppercase_first_letter(key))
267+
} else {
268+
"String".to_string()
269+
}
270+
}
215271
"boolean" => "bool".to_string(),
216272
"date" => extract_date_type(value)?,
217273
"number" => extract_number_type(value)?,
@@ -239,7 +295,7 @@ fn analyze_object_properties(
239295
// Create member and wrap types correctly
240296
let member_doc = value.description.clone();
241297
if reqs.contains(key) {
242-
debug!("with required member {} of type {}", key, rust_type);
298+
debug!("with required member {} of type {}", key, &rust_type);
243299
members.push(OutputMember {
244300
type_: rust_type,
245301
name: key.to_string(),
@@ -262,6 +318,7 @@ fn analyze_object_properties(
262318
members,
263319
level,
264320
docs: schema.description.clone(),
321+
is_enum,
265322
});
266323
Ok(results)
267324
}
@@ -496,34 +553,46 @@ type: object
496553
}
497554

498555
#[test]
499-
fn enum_one_of() {
556+
fn enum_string() {
500557
let schema_str = r#"
501-
operator:
502-
enum:
503-
- In
504-
- NotIn
505-
- Exists
506-
- DoesNotExist
507-
type: string"#;
558+
properties:
559+
operator:
560+
enum:
561+
- In
562+
- NotIn
563+
- Exists
564+
- DoesNotExist
565+
type: string
566+
required:
567+
- operator
568+
type: object
569+
"#;
508570

509571
let schema: JSONSchemaProps = serde_yaml::from_str(schema_str).unwrap();
510572
env_logger::init();
511573
let mut structs = vec![];
512-
analyze(schema, "", "Operator", 0, &mut structs).unwrap();
574+
analyze(schema, "", "MatchExpressions", 0, &mut structs).unwrap();
513575
println!("got {:?}", structs);
514576
let root = &structs[0];
515-
assert_eq!(root.name, "Operator");
577+
assert_eq!(root.name, "MatchExpressions");
516578
assert_eq!(root.level, 0);
579+
assert_eq!(&root.members[0].name, "operator");
580+
assert_eq!(&root.members[0].type_, "MatchExpressionsOperator");
581+
582+
// operator member
583+
let op = &structs[1];
584+
assert!(op.is_enum);
585+
assert_eq!(op.name, "MatchExpressionsOperator");
517586

518587
// should have enum members:
519-
assert_eq!(&root.members[0].name, "In");
520-
assert_eq!(&root.members[0].type_, "");
521-
assert_eq!(&root.members[1].name, "NotIn");
522-
assert_eq!(&root.members[1].type_, "");
523-
assert_eq!(&root.members[2].name, "Exists");
524-
assert_eq!(&root.members[2].type_, "");
525-
assert_eq!(&root.members[3].name, "DoesNotExist");
526-
assert_eq!(&root.members[3].type_, "");
588+
assert_eq!(&op.members[0].name, "In");
589+
assert_eq!(&op.members[0].type_, "");
590+
assert_eq!(&op.members[1].name, "NotIn");
591+
assert_eq!(&op.members[1].type_, "");
592+
assert_eq!(&op.members[2].name, "Exists");
593+
assert_eq!(&op.members[2].type_, "");
594+
assert_eq!(&op.members[3].name, "DoesNotExist");
595+
assert_eq!(&op.members[3].type_, "");
527596
}
528597

529598
#[test]

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub struct OutputStruct {
88
pub level: u8,
99
pub members: Vec<OutputMember>,
1010
pub docs: Option<String>,
11+
pub is_enum: bool,
1112
}
1213

1314
/// Output member belonging to an OutputStruct

0 commit comments

Comments
 (0)