diff --git a/src/lib.rs b/src/lib.rs index c6e5804..60fbd55 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,45 @@ use okapi::openapi3::{Components, OpenApi, SchemaObject}; use okapi::schemars::schema::{InstanceType, Schema, SingleOrVec}; +use serde_json::Value; + +fn recurse_fix(mut v: &mut Value) { + match &mut v { + Value::Array(array) => { + for item in array { + recurse_fix(item); + } + } + Value::Object(obj) => { + for item in obj.iter_mut() { + recurse_fix(item.1); + } + + if !obj.contains_key("examples") { + if let Some(ex) = obj.get("example").cloned() { + obj.insert("examples".to_string(), Value::Array(vec![ex])); + } + } + } + + _ => {} + } +} + +/// Parse OpenAPI 3 schema, treating "example" field as "examples" +/// +/// Otherwise, examples would be lost +pub fn parse_schema_fix_example_issue(file_content: &str) -> OpenApi { + let mut root = serde_yaml::from_str::(file_content) + .expect("Failed to parse OpenAPI document as YAML document!"); + + if let Value::Object(root_obj) = &mut root { + if let Some(components) = root_obj.get_mut("components") { + recurse_fix(components); + } + } + + parse_schema(&serde_yaml::to_string(&root).unwrap()) +} /// Parse OpenAPI 3 schema pub fn parse_schema(file_content: &str) -> OpenApi { diff --git a/src/main.rs b/src/main.rs index 9fee0ce..b819236 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,7 @@ use clap::{Parser, Subcommand}; -use openapi_parser::{build_tree, parse_schema, NodeType, ObjectChild, TreeNode}; +use openapi_parser::{ + build_tree, parse_schema, parse_schema_fix_example_issue, NodeType, ObjectChild, TreeNode, +}; use std::fmt::Write; /// Dump the tree structure of a schema element as dot file @@ -17,6 +19,10 @@ struct Args { #[arg(short, long, default_value = "Pet")] struct_name: String, + /// Treat "example" field as "examples" + #[arg(long)] + fix_example: bool, + /// The action to perform #[clap(subcommand)] action: Action, @@ -48,7 +54,10 @@ fn main() { Some(path) => std::fs::read_to_string(path).expect("Unable to load schema file!"), }; - let schema = parse_schema(&file_content); + let schema = match args.fix_example { + true => parse_schema_fix_example_issue(&file_content), + false => parse_schema(&file_content), + }; let components = schema.components.as_ref().unwrap(); if args.action == (Action::Tex { single: false }) {