@@ -28,7 +28,11 @@ pub(crate) struct Api {
28
28
}
29
29
30
30
impl Api {
31
- pub ( crate ) fn new ( paths : openapi:: Paths , with_deprecated : bool ) -> anyhow:: Result < Self > {
31
+ pub ( crate ) fn new (
32
+ paths : openapi:: Paths ,
33
+ with_deprecated : bool ,
34
+ component_schemas : & IndexMap < String , openapi:: SchemaObject > ,
35
+ ) -> anyhow:: Result < Self > {
32
36
let mut resources = BTreeMap :: new ( ) ;
33
37
34
38
for ( path, pi) in paths {
@@ -46,7 +50,9 @@ impl Api {
46
50
continue ;
47
51
}
48
52
49
- if let Some ( ( res_path, op) ) = Operation :: from_openapi ( & path, method, op) {
53
+ if let Some ( ( res_path, op) ) =
54
+ Operation :: from_openapi ( & path, method, op, & component_schemas)
55
+ {
50
56
let resource = get_or_insert_resource ( & mut resources, res_path) ;
51
57
if op. method == "post" {
52
58
resource. has_post_operation = true ;
@@ -223,6 +229,10 @@ struct Operation {
223
229
/// Name of the request body type, if any.
224
230
#[ serde( skip_serializing_if = "Option::is_none" ) ]
225
231
request_body_schema_name : Option < String > ,
232
+ /// Some request bodies are required, but all the fields are optional (i.e. the CLI can omit
233
+ /// this from the argument list).
234
+ /// Only useful when `request_body_schema_name` is `Some`.
235
+ request_body_all_optional : bool ,
226
236
/// Name of the response body type, if any.
227
237
#[ serde( skip_serializing_if = "Option::is_none" ) ]
228
238
response_body_schema_name : Option < String > ,
@@ -234,6 +244,7 @@ impl Operation {
234
244
path : & str ,
235
245
method : & str ,
236
246
op : openapi:: Operation ,
247
+ component_schemas : & IndexMap < String , aide:: openapi:: SchemaObject > ,
237
248
) -> Option < ( Vec < String > , Self ) > {
238
249
let Some ( op_id) = op. operation_id else {
239
250
// ignore operations without an operationId
@@ -343,6 +354,51 @@ impl Operation {
343
354
}
344
355
}
345
356
357
+ let request_body_all_optional = op
358
+ . request_body
359
+ . as_ref ( )
360
+ . map ( |r| {
361
+ match r {
362
+ ReferenceOr :: Reference { .. } => {
363
+ unimplemented ! ( "reference" )
364
+ }
365
+ ReferenceOr :: Item ( body) => {
366
+ if let Some ( mt) = body. content . get ( "application/json" ) {
367
+ match mt. schema . as_ref ( ) . map ( |so| & so. json_schema ) {
368
+ Some ( Schema :: Object ( schemars:: schema:: SchemaObject {
369
+ object : Some ( ov) ,
370
+ ..
371
+ } ) ) => {
372
+ return ov. required . is_empty ( ) ;
373
+ }
374
+ Some ( Schema :: Object ( schemars:: schema:: SchemaObject {
375
+ reference : Some ( s) ,
376
+ ..
377
+ } ) ) => {
378
+ match component_schemas
379
+ . get (
380
+ & get_schema_name ( Some ( s) ) . expect ( "schema should exist" ) ,
381
+ )
382
+ . map ( |so| & so. json_schema )
383
+ {
384
+ Some ( Schema :: Object ( schemars:: schema:: SchemaObject {
385
+ object : Some ( ov) ,
386
+ ..
387
+ } ) ) => {
388
+ return ov. required . is_empty ( ) ;
389
+ }
390
+ _ => unimplemented ! ( "double ref not supported" ) ,
391
+ }
392
+ }
393
+ _ => { }
394
+ }
395
+ }
396
+ }
397
+ }
398
+ false
399
+ } )
400
+ . unwrap_or_default ( ) ;
401
+
346
402
let request_body_schema_name = op. request_body . and_then ( |b| match b {
347
403
ReferenceOr :: Item ( mut req_body) => {
348
404
assert ! ( req_body. required) ;
@@ -362,7 +418,7 @@ impl Operation {
362
418
if !obj. is_ref ( ) {
363
419
tracing:: error!( ?obj, "unexpected non-$ref json body schema" ) ;
364
420
}
365
- get_schema_name ( obj. reference )
421
+ get_schema_name ( obj. reference . as_deref ( ) )
366
422
}
367
423
}
368
424
}
@@ -415,6 +471,7 @@ impl Operation {
415
471
header_params,
416
472
query_params,
417
473
request_body_schema_name,
474
+ request_body_all_optional,
418
475
response_body_schema_name,
419
476
} ;
420
477
Some ( ( res_path, op) )
@@ -458,7 +515,7 @@ fn response_body_schema_name(resp: ReferenceOr<openapi::Response>) -> Option<Str
458
515
if !obj. is_ref ( ) {
459
516
tracing:: error!( ?obj, "unexpected non-$ref json body schema" ) ;
460
517
}
461
- get_schema_name ( obj. reference )
518
+ get_schema_name ( obj. reference . as_deref ( ) )
462
519
}
463
520
}
464
521
}
0 commit comments