@@ -8,6 +8,17 @@ use crate::schema_utility_extensions::SchemaUtilityExtensions;
88
99/// Transforms the default generated schema for optional fields into a more idiomatic representation.
1010///
11+ /// This transform only applies to `struct` types that define one or more fields as [`Option<T>`].
12+ /// It iterates over every field in the `properties` keyword, skipping any fields that are defined
13+ /// in the `required` keyword.
14+ ///
15+ /// # Panics
16+ ///
17+ /// This transform panics if any apparently optional field doesn't define either:
18+ ///
19+ /// - `type` as an array where one value is `"null"`
20+ /// - `anyOf` with exactly two subschemas, one of which is just `{ "type": "null" }`
21+ ///
1122/// # Example
1223///
1324/// ```rust
@@ -69,24 +80,22 @@ pub fn idiomaticize_option_field(schema: &mut Schema) {
6980 // First, handle the case where the schema defines `type` with two values, one of which is
7081 // `"null"`. This is emitted by schemars for `Option<T>` fields where `T` is a type that
7182 // schemars implemented `JsonSchema` for, like `String` or `i32`.
72- if let Some ( types) = lookup_schema. get_keyword_as_array ( "type" ) {
73- if types. len ( ) == 2 && types. contains ( & json ! ( "null" ) ) {
83+ if let Some ( types) = lookup_schema. get_keyword_as_array ( "type" )
84+ && types. len ( ) == 2 && types. contains ( & json ! ( "null" ) ) {
7485 let actual_type = types. iter ( ) . find ( |t| t != & & serde_json:: json!( "null" ) ) ;
7586 schema. insert ( "type" . to_string ( ) , actual_type. unwrap ( ) . clone ( ) ) ;
7687
7788 munged_schema = true ;
78- }
7989 }
8090
8191 // Handle `null` in `enum` keyword - remove if needed.
82- if let Some ( enum_values) = lookup_schema. get_keyword_as_array ( "enum" ) {
83- if enum_values. contains ( & json ! ( null) ) {
92+ if let Some ( enum_values) = lookup_schema. get_keyword_as_array ( "enum" )
93+ && enum_values. contains ( & json ! ( null) ) {
8494 let mut new_enum_values = enum_values. clone ( ) ;
8595 new_enum_values. retain ( |v| v != & json ! ( null) ) ;
8696 schema. insert ( "enum" . to_string ( ) , json ! ( new_enum_values) ) ;
8797
8898 munged_schema = true ;
89- }
9099 }
91100
92101 // If we munged the schema for type/enum, return early. The remaining code handles cases where
@@ -121,7 +130,7 @@ pub fn idiomaticize_option_field(schema: &mut Schema) {
121130
122131 let null_schema = any_ofs
123132 . iter ( )
124- . find ( |s| s. get ( "type" ) . map ( |t| t == "null" ) . unwrap_or ( false ) ) ;
133+ . find ( |s| s. get ( "type" ) . is_some_and ( |t| t == "null" ) ) ;
125134 if null_schema. is_none ( ) {
126135 panic_t ! (
127136 "transforms.idiomaticize_option_field.null_schema_missing" ,
@@ -130,7 +139,7 @@ pub fn idiomaticize_option_field(schema: &mut Schema) {
130139 }
131140 let actual_schema = any_ofs
132141 . iter ( )
133- . find ( |s| s. get ( "type" ) . map ( |t| t != "null" ) . unwrap_or ( true ) ) ;
142+ . find ( |s| s. get ( "type" ) . is_none_or ( |t| t != "null" ) ) ;
134143 if actual_schema. is_none ( ) {
135144 panic_t ! (
136145 "transforms.idiomaticize_option_field.actual_schema_missing" ,
0 commit comments