Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion typify-impl/src/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl TypeSpace {
// new name for the inner type; otherwise, the inner type
// can just have this name.
let inner_type_name = match &type_name {
Name::Required(name) => Name::Suggested(format!("{}Inner", name)),
Name::Required(name) => Name::Required(format!("{}Inner", name)),
_ => type_name,
};
self.convert_option(inner_type_name, metadata, &ss)
Expand Down
12 changes: 9 additions & 3 deletions typify-impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -915,9 +915,15 @@ impl TypeSpace {
);

// Add all types.
self.id_to_entry
.values()
.for_each(|type_entry| type_entry.output(self, &mut output));
let mut output_names = BTreeSet::new();
self.id_to_entry.values().for_each(|type_entry| {
if type_entry
.name()
.is_none_or(|name| output_names.insert(name.clone()))
{
type_entry.output(self, &mut output);
}
});

// Add all shared default functions.
self.defaults
Expand Down
71 changes: 70 additions & 1 deletion typify-impl/tests/test_generation.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2022 Oxide Computer Company

use quote::quote;
use schemars::{gen::SchemaGenerator, schema::Schema, JsonSchema};
use schemars::{gen::SchemaGenerator, schema::RootSchema, schema::Schema, JsonSchema};
use serde::Serialize;
use typify_impl::{TypeSpace, TypeSpacePatch, TypeSpaceSettings};

Expand Down Expand Up @@ -112,3 +112,72 @@ fn test_generation() {

expectorate::assert_contents("tests/generator.out", fmt.as_str());
}

#[test]
fn test_required_nullable_object_with_title_uses_distinct_inner_name() {
let schema: RootSchema = serde_json::from_value(serde_json::json!({
"definitions": {
"aaa-wrapper": {
"type": "object",
"properties": {
"author_association": {
"title": "author_association",
"type": "string",
"enum": ["OWNER", "MEMBER"]
}
}
},
"author-association": {
"title": "author_association",
"type": "string",
"enum": ["OWNER", "MEMBER"]
},
"simple-user": {
"title": "Simple User",
"type": "object",
"properties": {
"login": {
"type": "string"
}
},
"required": ["login"]
},
"auto-merge": {
"title": "Auto merge",
"type": ["object", "null"],
"properties": {
"enabled_by": {
"$ref": "#/definitions/simple-user"
},
"merge_method": {
"type": "string",
"enum": ["merge", "squash", "rebase"]
},
"commit_title": {
"type": "string"
},
"commit_message": {
"type": "string"
}
},
"required": [
"enabled_by",
"merge_method",
"commit_title",
"commit_message"
]
}
}
}))
.unwrap();

let mut type_space = TypeSpace::default();
type_space.add_root_schema(schema).unwrap();

let fmt = rustfmt_wrapper::rustfmt(type_space.to_stream().to_string()).unwrap();

assert!(fmt.contains("pub struct AutoMerge(pub ::std::option::Option<AutoMergeInner>);"));
assert!(fmt.contains("pub struct AutoMergeInner {"));
assert!(!fmt.contains("pub struct AutoMerge(pub ::std::option::Option<AutoMerge>);"));
assert_eq!(fmt.matches("pub enum AuthorAssociation {").count(), 1);
}