api-macro: support empty api macro on structs

The description comes from the doc comment, the field types
and description from field doc comments and types.
Previously we needed to add at least the hint that the
schema is an object schema. Now we support an empty #[api]
attribute as well.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2020-01-08 10:09:41 +01:00
parent 7c6ebbdbf3
commit 08e1cf3c2f
4 changed files with 26 additions and 5 deletions

View File

@ -109,6 +109,15 @@ impl Schema {
} }
} }
fn empty_object(span: Span) -> Self {
Self {
span,
description: None,
item: SchemaItem::Object(SchemaObject::new()),
properties: Vec::new(),
}
}
fn to_typed_schema(&self, ts: &mut TokenStream) -> Result<(), Error> { fn to_typed_schema(&self, ts: &mut TokenStream) -> Result<(), Error> {
self.item.to_schema( self.item.to_schema(
ts, ts,
@ -331,6 +340,12 @@ pub struct SchemaObject {
} }
impl SchemaObject { impl SchemaObject {
pub fn new() -> Self {
Self {
properties: Vec::new(),
}
}
fn try_extract_from(obj: &mut JSONObject) -> Result<Self, syn::Error> { fn try_extract_from(obj: &mut JSONObject) -> Result<Self, syn::Error> {
Ok(Self { Ok(Self {
properties: obj properties: obj

View File

@ -3,7 +3,7 @@ use std::convert::{TryFrom, TryInto};
use failure::Error; use failure::Error;
use proc_macro2::{Ident, TokenStream}; use proc_macro2::{Ident, Span, TokenStream};
use quote::quote_spanned; use quote::quote_spanned;
use super::Schema; use super::Schema;
@ -12,7 +12,11 @@ use crate::serde;
use crate::util::{self, FieldName, JSONObject}; use crate::util::{self, FieldName, JSONObject};
pub fn handle_struct(attribs: JSONObject, mut stru: syn::ItemStruct) -> Result<TokenStream, Error> { pub fn handle_struct(attribs: JSONObject, mut stru: syn::ItemStruct) -> Result<TokenStream, Error> {
let mut schema: Schema = attribs.try_into()?; let mut schema: Schema = if attribs.is_empty() {
Schema::empty_object(Span::call_site())
} else {
attribs.try_into()?
};
if schema.description.is_none() { if schema.description.is_none() {
let (doc_comment, doc_span) = util::get_doc_comments(&stru.attrs)?; let (doc_comment, doc_span) = util::get_doc_comments(&stru.attrs)?;

View File

@ -298,6 +298,10 @@ pub struct JSONObject {
} }
impl JSONObject { impl JSONObject {
pub fn is_empty(&self) -> bool {
self.elements.is_empty()
}
fn parse_elements(input: ParseStream) -> syn::Result<HashMap<FieldName, JSONValue>> { fn parse_elements(input: ParseStream) -> syn::Result<HashMap<FieldName, JSONValue>> {
let map_elems: Punctuated<JSONMapEntry, Token![,]> = let map_elems: Punctuated<JSONMapEntry, Token![,]> =
input.parse_terminated(JSONMapEntry::parse)?; input.parse_terminated(JSONMapEntry::parse)?;

View File

@ -16,9 +16,7 @@ use serde_json::Value;
//#[derive(Clone, Debug, Deserialize, Serialize)] //#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct OkString(String); pub struct OkString(String);
#[api( #[api]
properties: {}
)]
/// A Foo. /// A Foo.
pub struct Foo { pub struct Foo {
/// A test string. /// A test string.