Skip to content

Commit f5c8987

Browse files
committed
Optional request bodies
The idea is to identify args for the CLI that can be omitted since the entire body is technically optional.
1 parent 0524d30 commit f5c8987

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

src/api.rs

+38-1
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,10 @@ struct Operation {
223223
/// Name of the request body type, if any.
224224
#[serde(skip_serializing_if = "Option::is_none")]
225225
request_body_schema_name: Option<String>,
226+
/// Some request bodies are required, but all the fields are optional (i.e. the CLI can omit
227+
/// this from the argument list).
228+
/// Only useful when `request_body_schema_name` is `Some`.
229+
request_body_all_optional: bool,
226230
/// Name of the response body type, if any.
227231
#[serde(skip_serializing_if = "Option::is_none")]
228232
response_body_schema_name: Option<String>,
@@ -343,7 +347,7 @@ impl Operation {
343347
}
344348
}
345349

346-
let request_body_schema_name = op.request_body.and_then(|b| match b {
350+
let request_body_schema_name = op.request_body.clone().and_then(|b| match b {
347351
ReferenceOr::Item(mut req_body) => {
348352
assert!(req_body.required);
349353
assert!(req_body.extensions.is_empty());
@@ -372,6 +376,38 @@ impl Operation {
372376
}
373377
});
374378

379+
let request_body_all_optional = op
380+
.request_body
381+
.map(|r| {
382+
match r {
383+
ReferenceOr::Reference { .. } => {
384+
todo!("reference")
385+
}
386+
ReferenceOr::Item(body) => {
387+
if let Some(mt) = body.content.get("application/json") {
388+
match mt.schema.as_ref().map(|so| &so.json_schema) {
389+
Some(Schema::Object(schemars::schema::SchemaObject {
390+
object: Some(ov),
391+
..
392+
})) => {
393+
dbg!((&op_id, ov.required.is_empty()));
394+
return ov.required.is_empty();
395+
}
396+
Some(Schema::Object(schemars::schema::SchemaObject {
397+
reference: Some(s),
398+
..
399+
})) => {
400+
todo!("lookup {s}");
401+
}
402+
_ => {}
403+
}
404+
}
405+
}
406+
}
407+
false
408+
})
409+
.unwrap_or_default();
410+
375411
let response_body_schema_name = op.responses.and_then(|r| {
376412
assert_eq!(r.default, None);
377413
assert!(r.extensions.is_empty());
@@ -415,6 +451,7 @@ impl Operation {
415451
header_params,
416452
query_params,
417453
request_body_schema_name,
454+
request_body_all_optional,
418455
response_body_schema_name,
419456
};
420457
Some((res_path, op))

templates/svix_cli_resource.rs.jinja

+6-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,12 @@ pub enum {{ resource_type_name }}Commands {
8686
{# body parameter struct -#}
8787
{% if op.request_body_schema_name is defined -%}
8888
{{ op.request_body_schema_name | to_snake_case }}:
89-
JsonOf<{{ op.request_body_schema_name }}>,
89+
{% if op.request_body_all_optional %}
90+
Option<JsonOf<{{ op.request_body_schema_name }}>>
91+
{% else %}
92+
JsonOf<{{ op.request_body_schema_name }}>
93+
{% endif %}
94+
,
9095
{% endif -%}
9196

9297
{# query parameters -#}

0 commit comments

Comments
 (0)