@@ -3,12 +3,19 @@ use schemars::schema::{
33 ArrayValidation , InstanceType , Metadata , ObjectValidation , Schema , SchemaObject , SingleOrVec ,
44} ;
55
6+ pub struct ToJsonSchemaOptions {
7+ /// If true, mark all fields as required.
8+ /// Use union type (with `null`) for optional fields instead.
9+ /// Models like OpenAI will reject the schema if a field is not required.
10+ pub fields_always_required : bool ,
11+ }
12+
613pub trait ToJsonSchema {
7- fn to_json_schema ( & self ) -> SchemaObject ;
14+ fn to_json_schema ( & self , options : & ToJsonSchemaOptions ) -> SchemaObject ;
815}
916
1017impl ToJsonSchema for schema:: BasicValueType {
11- fn to_json_schema ( & self ) -> SchemaObject {
18+ fn to_json_schema ( & self , options : & ToJsonSchemaOptions ) -> SchemaObject {
1219 let mut schema = SchemaObject :: default ( ) ;
1320 match self {
1421 schema:: BasicValueType :: Str => {
@@ -59,7 +66,7 @@ impl ToJsonSchema for schema::BasicValueType {
5966 schema. instance_type = Some ( SingleOrVec :: Single ( Box :: new ( InstanceType :: Array ) ) ) ;
6067 schema. array = Some ( Box :: new ( ArrayValidation {
6168 items : Some ( SingleOrVec :: Single ( Box :: new (
62- s. element_type . to_json_schema ( ) . into ( ) ,
69+ s. element_type . to_json_schema ( options ) . into ( ) ,
6370 ) ) ) ,
6471 min_items : s. dimension . and_then ( |d| u32:: try_from ( d) . ok ( ) ) ,
6572 max_items : s. dimension . and_then ( |d| u32:: try_from ( d) . ok ( ) ) ,
@@ -72,7 +79,7 @@ impl ToJsonSchema for schema::BasicValueType {
7279}
7380
7481impl ToJsonSchema for schema:: StructSchema {
75- fn to_json_schema ( & self ) -> SchemaObject {
82+ fn to_json_schema ( & self , options : & ToJsonSchemaOptions ) -> SchemaObject {
7683 SchemaObject {
7784 metadata : Some ( Box :: new ( Metadata {
7885 description : self . description . as_ref ( ) . map ( |s| s. to_string ( ) ) ,
@@ -83,12 +90,25 @@ impl ToJsonSchema for schema::StructSchema {
8390 properties : self
8491 . fields
8592 . iter ( )
86- . map ( |f| ( f. name . to_string ( ) , f. value_type . to_json_schema ( ) . into ( ) ) )
93+ . map ( |f| {
94+ let mut schema = f. value_type . to_json_schema ( options) ;
95+ if options. fields_always_required && f. value_type . nullable {
96+ if let Some ( instance_type) = & mut schema. instance_type {
97+ let mut types = match instance_type {
98+ SingleOrVec :: Single ( t) => vec ! [ * * t] ,
99+ SingleOrVec :: Vec ( t) => std:: mem:: take ( t) ,
100+ } ;
101+ types. push ( InstanceType :: Null ) ;
102+ * instance_type = SingleOrVec :: Vec ( types) ;
103+ }
104+ }
105+ ( f. name . to_string ( ) , schema. into ( ) )
106+ } )
87107 . collect ( ) ,
88108 required : self
89109 . fields
90110 . iter ( )
91- . filter ( |& f| ( !f. value_type . nullable ) )
111+ . filter ( |& f| ( options . fields_always_required || !f. value_type . nullable ) )
92112 . map ( |f| f. name . to_string ( ) )
93113 . collect ( ) ,
94114 additional_properties : Some ( Schema :: Bool ( false ) . into ( ) ) ,
@@ -100,14 +120,16 @@ impl ToJsonSchema for schema::StructSchema {
100120}
101121
102122impl ToJsonSchema for schema:: ValueType {
103- fn to_json_schema ( & self ) -> SchemaObject {
123+ fn to_json_schema ( & self , options : & ToJsonSchemaOptions ) -> SchemaObject {
104124 match self {
105- schema:: ValueType :: Basic ( b) => b. to_json_schema ( ) ,
106- schema:: ValueType :: Struct ( s) => s. to_json_schema ( ) ,
125+ schema:: ValueType :: Basic ( b) => b. to_json_schema ( options ) ,
126+ schema:: ValueType :: Struct ( s) => s. to_json_schema ( options ) ,
107127 schema:: ValueType :: Collection ( c) => SchemaObject {
108128 instance_type : Some ( SingleOrVec :: Single ( Box :: new ( InstanceType :: Array ) ) ) ,
109129 array : Some ( Box :: new ( ArrayValidation {
110- items : Some ( SingleOrVec :: Single ( Box :: new ( c. row . to_json_schema ( ) . into ( ) ) ) ) ,
130+ items : Some ( SingleOrVec :: Single ( Box :: new (
131+ c. row . to_json_schema ( options) . into ( ) ,
132+ ) ) ) ,
111133 ..Default :: default ( )
112134 } ) ) ,
113135 ..Default :: default ( )
@@ -117,7 +139,7 @@ impl ToJsonSchema for schema::ValueType {
117139}
118140
119141impl ToJsonSchema for schema:: EnrichedValueType {
120- fn to_json_schema ( & self ) -> SchemaObject {
121- self . typ . to_json_schema ( )
142+ fn to_json_schema ( & self , options : & ToJsonSchemaOptions ) -> SchemaObject {
143+ self . typ . to_json_schema ( options )
122144 }
123145}
0 commit comments