@@ -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 , aide:: 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
@@ -342,6 +353,50 @@ impl Operation {
342
353
}
343
354
}
344
355
}
356
+ let request_body_all_optional = op
357
+ . request_body
358
+ . as_ref ( )
359
+ . map ( |r| {
360
+ match r {
361
+ ReferenceOr :: Reference { .. } => {
362
+ unimplemented ! ( "reference" )
363
+ }
364
+ ReferenceOr :: Item ( body) => {
365
+ if let Some ( mt) = body. content . get ( "application/json" ) {
366
+ match mt. schema . as_ref ( ) . map ( |so| & so. json_schema ) {
367
+ Some ( Schema :: Object ( schemars:: schema:: SchemaObject {
368
+ object : Some ( ov) ,
369
+ ..
370
+ } ) ) => {
371
+ return ov. required . is_empty ( ) ;
372
+ }
373
+ Some ( Schema :: Object ( schemars:: schema:: SchemaObject {
374
+ reference : Some ( s) ,
375
+ ..
376
+ } ) ) => {
377
+ match component_schemas
378
+ . get (
379
+ & get_schema_name ( Some ( s) ) . expect ( "schema should exist" ) ,
380
+ )
381
+ . map ( |so| & so. json_schema )
382
+ {
383
+ Some ( Schema :: Object ( schemars:: schema:: SchemaObject {
384
+ object : Some ( ov) ,
385
+ ..
386
+ } ) ) => {
387
+ return ov. required . is_empty ( ) ;
388
+ }
389
+ _ => unimplemented ! ( "double ref not supported" ) ,
390
+ }
391
+ }
392
+ _ => { }
393
+ }
394
+ }
395
+ }
396
+ }
397
+ false
398
+ } )
399
+ . unwrap_or_default ( ) ;
345
400
346
401
let request_body_schema_name = op. request_body . and_then ( |b| match b {
347
402
ReferenceOr :: Item ( mut req_body) => {
@@ -362,7 +417,7 @@ impl Operation {
362
417
if !obj. is_ref ( ) {
363
418
tracing:: error!( ?obj, "unexpected non-$ref json body schema" ) ;
364
419
}
365
- get_schema_name ( obj. reference )
420
+ get_schema_name ( obj. reference . as_deref ( ) )
366
421
}
367
422
}
368
423
}
@@ -415,6 +470,7 @@ impl Operation {
415
470
header_params,
416
471
query_params,
417
472
request_body_schema_name,
473
+ request_body_all_optional,
418
474
response_body_schema_name,
419
475
} ;
420
476
Some ( ( res_path, op) )
@@ -458,7 +514,7 @@ fn response_body_schema_name(resp: ReferenceOr<openapi::Response>) -> Option<Str
458
514
if !obj. is_ref ( ) {
459
515
tracing:: error!( ?obj, "unexpected non-$ref json body schema" ) ;
460
516
}
461
- get_schema_name ( obj. reference )
517
+ get_schema_name ( obj. reference . as_deref ( ) )
462
518
}
463
519
}
464
520
}
0 commit comments