Skip to content

Commit

Permalink
0.1.3: implement schema kinds and enum handling
Browse files Browse the repository at this point in the history
  • Loading branch information
kshyr committed Apr 4, 2024
1 parent b4d6ed4 commit 01b6941
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 34 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "openapi-to-jsdoc"
version = "0.1.2"
version = "0.1.3"
edition = "2021"
description = "Generate JSDoc typedefs from OpenAPI 3.0.x spec schemas"
license = "MIT"
Expand Down
155 changes: 123 additions & 32 deletions src/jsdoc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,39 +26,39 @@ pub fn generate_typedef(file: String, spec: &OpenAPI, schema_name: &str) -> Stri
.unwrap()
.to_string(),
RefOr::Item(item) => match &item.kind {
SchemaKind::Type(t) => match t {
Type::String(_) => "string".to_string(),
Type::Number(_) => "number".to_string(),
Type::Integer(_) => "number".to_string(),
Type::Boolean {} => "boolean".to_string(),
Type::Object(_) => "Object".to_string(),
Type::Array(array) => {
let item = *array.items.clone().unwrap();
let item_type: String = match item {
RefOr::Reference { reference } => {
let mut reference = reference
.strip_prefix("#/components/schemas/")
.unwrap()
.to_string();
reference.push_str("[]");
reference
}
RefOr::Item(item) => match &item.kind {
SchemaKind::Type(t) => match t {
Type::String(_) => "string[]".to_string(),
Type::Number(_) => "number[]".to_string(),
Type::Integer(_) => "number[]".to_string(),
Type::Boolean {} => "boolean[]".to_string(),
Type::Object(_) => "Object[]".to_string(),
_ => todo!(),
},
_ => todo!(),
},
};
item_type
SchemaKind::Type(t) => get_prop_type(t),
SchemaKind::OneOf { one_of } => {
// union type
let mut union = String::new();
for (i, item) in one_of.iter().enumerate() {
let item_type = get_item_type(item);
let union_sign = if i == one_of.len() - 1 { "" } else { " | " };
union.push_str(format!("{} {}", item_type, union_sign).as_str());
}
},
_ => todo!(),
union
}
SchemaKind::AllOf { all_of } => {
let mut intersection = String::new();
for (i, item) in all_of.iter().enumerate() {
let item_type = get_item_type(item);
let union_sign = if i == all_of.len() - 1 { "" } else { " & " };
intersection.push_str(format!("{}{}", item_type, union_sign).as_str());
}
intersection
}
SchemaKind::AnyOf { any_of } => {
println!(" AnyOf {:?}", any_of);
"Object".to_string()
}

SchemaKind::Not { not } => {
println!("Not {:?}", not);
"Object".to_string()
}
SchemaKind::Any(_) => {
println!("Any");
"Object".to_string()
}
},
};

Expand All @@ -81,3 +81,94 @@ pub fn generate_typedef(file: String, spec: &OpenAPI, schema_name: &str) -> Stri
fs::write(file, &doc).unwrap();
doc
}

fn get_item_type(item: &RefOr<openapiv3::Schema>) -> String {
match item {
RefOr::Reference { reference } => reference
.strip_prefix("#/components/schemas/")
.unwrap()
.to_string(),
RefOr::Item(item) => match &item.kind {
SchemaKind::Type(t) => get_prop_type(t),
_ => todo!(),
},
}
}

fn get_prop_type(t: &Type) -> String {
match t {
Type::String(s) => {
let enum_array = s
.enumeration
.iter()
.map(|x| format!(r#""{}""#, x))
.filter(|x| !x.is_empty())
.collect();
if let Some(en) = get_enum_type(&enum_array) {
return en;
}
println!("String {:?}", s);
"string".to_string()
}
Type::Number(n) => {
let enum_array = n
.enumeration
.iter()
.map(|x| {
if let Some(n_inner) = x {
n_inner.to_string()
} else {
"".to_string()
}
})
.filter(|x| !x.is_empty())
.collect();
if let Some(en) = get_enum_type(&enum_array) {
en
} else {
"number".to_string()
}
}
Type::Integer(_) => "number".to_string(),
Type::Boolean {} => "boolean".to_string(),
Type::Object(_) => "Object".to_string(),
Type::Array(array) => {
let item = *array.items.clone().unwrap();
let item_type: String = match item {
RefOr::Reference { reference } => {
let mut reference = reference
.strip_prefix("#/components/schemas/")
.unwrap()
.to_string();
reference.push_str("[]");
reference
}
RefOr::Item(item) => match &item.kind {
SchemaKind::Type(t) => match t {
Type::String(_) => "string[]".to_string(),
Type::Number(_) => "number[]".to_string(),
Type::Integer(_) => "number[]".to_string(),
Type::Boolean {} => "boolean[]".to_string(),
Type::Object(_) => "Object[]".to_string(),
_ => todo!(),
},
_ => todo!(),
},
};
item_type
}
}
}

fn get_enum_type(enums: &Vec<String>) -> Option<String> {
if enums.is_empty() {
return None;
}

let mut enum_type = String::new();
for (i, value) in enums.iter().enumerate() {
let union_sign = if i == enums.len() - 1 { "" } else { " | " };
enum_type.push_str(format!("{}{}", value, union_sign).as_str());
}
Some(enum_type)
}

0 comments on commit 01b6941

Please sign in to comment.