mirror of
https://git.proxmox.com/git/proxmox
synced 2025-08-04 19:02:23 +00:00
api-macro: make type optional in some cases
Objects and arrays are now optionally identified by their 'properties' or 'items' property if their 'type' is left out. Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
5b41f68891
commit
7f7a9fe92f
@ -129,14 +129,6 @@ struct JSONObject {
|
|||||||
pub elements: HashMap<SimpleIdent, JSONValue>,
|
pub elements: HashMap<SimpleIdent, JSONValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
//impl TryFrom<JSONValue> for JSONObject {
|
|
||||||
// type Error = syn::Error;
|
|
||||||
//
|
|
||||||
// fn try_from(value: JSONValue) -> Result<Self, syn::Error> {
|
|
||||||
// value.into_object()
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
impl Parse for JSONObject {
|
impl Parse for JSONObject {
|
||||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||||
let content;
|
let content;
|
||||||
@ -157,15 +149,25 @@ impl Parse for JSONObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::ops::Deref for JSONObject {
|
||||||
|
type Target = HashMap<SimpleIdent, JSONValue>;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.elements
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::DerefMut for JSONObject {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.elements
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl JSONObject {
|
impl JSONObject {
|
||||||
fn span(&self) -> Span {
|
fn span(&self) -> Span {
|
||||||
self.brace_token.span
|
self.brace_token.span
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove(&mut self, name: &str) -> Option<JSONValue> {
|
|
||||||
self.elements.remove(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_required_element(&mut self, name: &str) -> Result<JSONValue, syn::Error> {
|
fn remove_required_element(&mut self, name: &str) -> Result<JSONValue, syn::Error> {
|
||||||
self.remove(name)
|
self.remove(name)
|
||||||
.ok_or_else(|| format_err!(self.span(), "missing required element: {}", name))
|
.ok_or_else(|| format_err!(self.span(), "missing required element: {}", name))
|
||||||
@ -309,8 +311,23 @@ enum SchemaItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SchemaItem {
|
impl SchemaItem {
|
||||||
|
/// If there's a `type` specified, parse it as that type. Otherwise check for keys which
|
||||||
|
/// uniqueply identify the type, such as "properties" for type `Object`.
|
||||||
fn try_extract_from(obj: &mut JSONObject) -> Result<Self, syn::Error> {
|
fn try_extract_from(obj: &mut JSONObject) -> Result<Self, syn::Error> {
|
||||||
match SimpleIdent::try_from(obj.remove_required_element("type")?)?.as_str() {
|
let ty = obj.remove("type").map(SimpleIdent::try_from).transpose()?;
|
||||||
|
let ty = match &ty {
|
||||||
|
Some(ty) => ty.as_str(),
|
||||||
|
None => {
|
||||||
|
if obj.contains_key("properties") {
|
||||||
|
"Object"
|
||||||
|
} else if obj.contains_key("items") {
|
||||||
|
"Array"
|
||||||
|
} else {
|
||||||
|
bail!(obj.span(), "failed to guess 'type' in schema definition");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match ty {
|
||||||
"Null" => Ok(SchemaItem::Null),
|
"Null" => Ok(SchemaItem::Null),
|
||||||
"Boolean" => Ok(SchemaItem::Boolean),
|
"Boolean" => Ok(SchemaItem::Boolean),
|
||||||
"Integer" => Ok(SchemaItem::Integer),
|
"Integer" => Ok(SchemaItem::Integer),
|
||||||
|
@ -8,7 +8,6 @@ use serde_json::Value;
|
|||||||
|
|
||||||
#[api]
|
#[api]
|
||||||
#[input({
|
#[input({
|
||||||
type: Object,
|
|
||||||
properties: {
|
properties: {
|
||||||
username: {
|
username: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -22,7 +21,6 @@ use serde_json::Value;
|
|||||||
}
|
}
|
||||||
})]
|
})]
|
||||||
#[returns({
|
#[returns({
|
||||||
type: Object,
|
|
||||||
description: "Returns a ticket",
|
description: "Returns a ticket",
|
||||||
properties: {
|
properties: {
|
||||||
"username": {
|
"username": {
|
||||||
|
Loading…
Reference in New Issue
Block a user