Skip to content

Commit

Permalink
Attribute for defining examples (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
GREsau committed May 17, 2020
1 parent 19b9bef commit e259955
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 3 deletions.
25 changes: 25 additions & 0 deletions schemars/tests/examples.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 39 additions & 0 deletions schemars/tests/expected/examples.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
8 changes: 7 additions & 1 deletion schemars_derive/src/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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
Expand Down
19 changes: 17 additions & 2 deletions schemars_derive/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
}

Expand All @@ -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,
}
}

Expand Down Expand Up @@ -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());
Expand Down

0 comments on commit e259955

Please sign in to comment.