Attribute for defining examples (#23)
This commit is contained in:
parent
19b9bef395
commit
e259955809
4 changed files with 88 additions and 3 deletions
25
schemars/tests/examples.rs
Normal file
25
schemars/tests/examples.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
mod util;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Serialize;
|
||||
use util::*;
|
||||
|
||||
#[derive(Default, Debug, JsonSchema, Serialize)]
|
||||
#[schemars(example = "Struct::default", example = "null")]
|
||||
pub struct Struct {
|
||||
#[schemars(example = "eight", example = "null")]
|
||||
foo: i32,
|
||||
bar: bool,
|
||||
#[schemars(example = "null")]
|
||||
baz: Option<&'static str>,
|
||||
}
|
||||
|
||||
fn eight() -> i32 {
|
||||
8
|
||||
}
|
||||
|
||||
fn null() -> () {}
|
||||
|
||||
#[test]
|
||||
fn examples() -> TestResult {
|
||||
test_default_generated_schema::<Struct>("examples")
|
||||
}
|
39
schemars/tests/expected/examples.json
Normal file
39
schemars/tests/expected/examples.json
Normal file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Struct",
|
||||
"examples": [
|
||||
{
|
||||
"bar": false,
|
||||
"baz": null,
|
||||
"foo": 0
|
||||
},
|
||||
null
|
||||
],
|
||||
"type": "object",
|
||||
"required": [
|
||||
"bar",
|
||||
"foo"
|
||||
],
|
||||
"properties": {
|
||||
"bar": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"baz": {
|
||||
"examples": [
|
||||
null
|
||||
],
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"foo": {
|
||||
"examples": [
|
||||
8,
|
||||
null
|
||||
],
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,7 +16,7 @@ pub struct Attrs {
|
|||
pub title: Option<String>,
|
||||
pub description: Option<String>,
|
||||
pub deprecated: bool,
|
||||
// TODO pub example: Option<syn::Path>,
|
||||
pub examples: Vec<syn::Path>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -111,6 +111,12 @@ impl Attrs {
|
|||
}
|
||||
}
|
||||
|
||||
Meta(NameValue(m)) if m.path.is_ident("example") => {
|
||||
if let Ok(fun) = parse_lit_into_path(errors, attr_type, "example", &m.lit) {
|
||||
self.examples.push(fun)
|
||||
}
|
||||
}
|
||||
|
||||
Meta(_meta_item) => {
|
||||
// TODO uncomment this for 0.8.0 (breaking change)
|
||||
// https://github.com/GREsau/schemars/issues/18
|
||||
|
|
|
@ -3,13 +3,14 @@ use attr::Attrs;
|
|||
use proc_macro2::{Ident, Span, TokenStream};
|
||||
use quote::{ToTokens, TokenStreamExt};
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SchemaMetadata<'a> {
|
||||
pub title: Option<&'a str>,
|
||||
pub description: Option<&'a str>,
|
||||
pub deprecated: bool,
|
||||
pub read_only: bool,
|
||||
pub write_only: bool,
|
||||
pub examples: &'a [syn::Path],
|
||||
pub default: Option<TokenStream>,
|
||||
}
|
||||
|
||||
|
@ -36,7 +37,10 @@ impl<'a> SchemaMetadata<'a> {
|
|||
title: attrs.title.as_ref().and_then(none_if_empty),
|
||||
description: attrs.description.as_ref().and_then(none_if_empty),
|
||||
deprecated: attrs.deprecated,
|
||||
..Default::default()
|
||||
examples: &attrs.examples,
|
||||
read_only: false,
|
||||
write_only: false,
|
||||
default: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,6 +84,17 @@ impl<'a> SchemaMetadata<'a> {
|
|||
});
|
||||
}
|
||||
|
||||
if !self.examples.is_empty() {
|
||||
let examples = self.examples.iter().map(|eg| {
|
||||
quote! {
|
||||
schemars::_serde_json::value::to_value(#eg())
|
||||
}
|
||||
});
|
||||
setters.push(quote! {
|
||||
metadata.examples = vec![#(#examples),*].into_iter().flatten().collect();
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(default) = &self.default {
|
||||
setters.push(quote! {
|
||||
metadata.default = #default.and_then(|d| schemars::_serde_json::value::to_value(d).ok());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue