Set readOnly/writeOnly on properties
This commit is contained in:
parent
68ddfa310f
commit
2bc3957cb8
5 changed files with 55 additions and 24 deletions
|
@ -126,7 +126,7 @@ impl SchemaGenerator {
|
||||||
|
|
||||||
pub fn root_schema_for<T: ?Sized + JsonSchema>(&mut self) -> Result<SchemaObject> {
|
pub fn root_schema_for<T: ?Sized + JsonSchema>(&mut self) -> Result<SchemaObject> {
|
||||||
let mut schema: SchemaObject = T::json_schema(self)?.into();
|
let mut schema: SchemaObject = T::json_schema(self)?.into();
|
||||||
let metadata = schema.metadata.get_or_insert_with(Default::default);
|
let metadata = schema.metadata();
|
||||||
metadata.schema = Some("http://json-schema.org/draft-07/schema#".to_owned());
|
metadata.schema = Some("http://json-schema.org/draft-07/schema#".to_owned());
|
||||||
metadata.title = Some(T::schema_name());
|
metadata.title = Some(T::schema_name());
|
||||||
metadata.definitions.extend(self.definitions().clone());
|
metadata.definitions.extend(self.definitions().clone());
|
||||||
|
@ -135,7 +135,7 @@ impl SchemaGenerator {
|
||||||
|
|
||||||
pub fn into_root_schema_for<T: ?Sized + JsonSchema>(mut self) -> Result<SchemaObject> {
|
pub fn into_root_schema_for<T: ?Sized + JsonSchema>(mut self) -> Result<SchemaObject> {
|
||||||
let mut schema: SchemaObject = T::json_schema(&mut self)?.into();
|
let mut schema: SchemaObject = T::json_schema(&mut self)?.into();
|
||||||
let metadata = schema.metadata.get_or_insert_with(Default::default);
|
let metadata = schema.metadata();
|
||||||
metadata.schema = Some("http://json-schema.org/draft-07/schema#".to_owned());
|
metadata.schema = Some("http://json-schema.org/draft-07/schema#".to_owned());
|
||||||
metadata.title = Some(T::schema_name());
|
metadata.title = Some(T::schema_name());
|
||||||
metadata.definitions.extend(self.into_definitions());
|
metadata.definitions.extend(self.into_definitions());
|
||||||
|
|
|
@ -77,6 +77,14 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! get_or_insert_default_fn {
|
||||||
|
($name:ident, $ret:path) => {
|
||||||
|
pub fn $name(&mut self) -> &mut $ret {
|
||||||
|
self.$name.get_or_insert_with(Default::default)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
impl SchemaObject {
|
impl SchemaObject {
|
||||||
pub fn new_ref(reference: String) -> Self {
|
pub fn new_ref(reference: String) -> Self {
|
||||||
SchemaObject {
|
SchemaObject {
|
||||||
|
@ -95,6 +103,13 @@ impl SchemaObject {
|
||||||
};
|
};
|
||||||
*self == only_ref
|
*self == only_ref
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_or_insert_default_fn!(metadata, Metadata);
|
||||||
|
get_or_insert_default_fn!(subschemas, SubschemaValidation);
|
||||||
|
get_or_insert_default_fn!(number, NumberValidation);
|
||||||
|
get_or_insert_default_fn!(string, StringValidation);
|
||||||
|
get_or_insert_default_fn!(array, ArrayValidation);
|
||||||
|
get_or_insert_default_fn!(object, ObjectValidation);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Schema> for SchemaObject {
|
impl From<Schema> for SchemaObject {
|
||||||
|
|
|
@ -3,16 +3,21 @@
|
||||||
"title": "MyStruct",
|
"title": "MyStruct",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
"included1",
|
"included",
|
||||||
"included2"
|
"writable"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"included1": {
|
"included": {
|
||||||
|
"type": "null"
|
||||||
|
},
|
||||||
|
"readable": {
|
||||||
|
"readOnly": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"writable": {
|
||||||
|
"writeOnly": true,
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"format": "float"
|
"format": "float"
|
||||||
},
|
|
||||||
"included2": {
|
|
||||||
"type": "null"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,10 +9,10 @@ struct MyStruct {
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
skipped2: bool,
|
skipped2: bool,
|
||||||
#[serde(skip_deserializing)]
|
#[serde(skip_deserializing)]
|
||||||
skipped3: String,
|
readable: String,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
included1: f32,
|
writable: f32,
|
||||||
included2: (),
|
included: (),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -21,15 +21,11 @@ fn skip_struct_fields() -> TestResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, JsonSchema)]
|
#[derive(Debug, JsonSchema)]
|
||||||
struct TupleStruct (
|
struct TupleStruct(
|
||||||
#[schemars(skip)]
|
#[schemars(skip)] i32,
|
||||||
i32,
|
#[serde(skip)] bool,
|
||||||
#[serde(skip)]
|
#[serde(skip_deserializing)] String,
|
||||||
bool,
|
#[serde(skip_serializing)] f32,
|
||||||
#[serde(skip_deserializing)]
|
|
||||||
String,
|
|
||||||
#[serde(skip_serializing)]
|
|
||||||
f32,
|
|
||||||
(),
|
(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -55,4 +51,3 @@ pub enum MyEnum {
|
||||||
fn skip_enum_variants() -> TestResult {
|
fn skip_enum_variants() -> TestResult {
|
||||||
test_default_generated_schema::<MyEnum>("skip_enum_variants")
|
test_default_generated_schema::<MyEnum>("skip_enum_variants")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -267,8 +267,9 @@ fn schema_for_tuple_struct(fields: &[Field]) -> TokenStream {
|
||||||
fn schema_for_struct(fields: &[Field], cattrs: &attr::Container) -> TokenStream {
|
fn schema_for_struct(fields: &[Field], cattrs: &attr::Container) -> TokenStream {
|
||||||
let (flat, nested): (Vec<_>, Vec<_>) = fields
|
let (flat, nested): (Vec<_>, Vec<_>) = fields
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|f| !f.attrs.skip_deserializing())
|
.filter(|f| !f.attrs.skip_deserializing() || !f.attrs.skip_serializing())
|
||||||
.partition(|f| f.attrs.flatten());
|
.partition(|f| f.attrs.flatten());
|
||||||
|
|
||||||
let container_has_default = has_default(cattrs.default());
|
let container_has_default = has_default(cattrs.default());
|
||||||
let mut required = Vec::new();
|
let mut required = Vec::new();
|
||||||
let recurse = nested.iter().map(|field| {
|
let recurse = nested.iter().map(|field| {
|
||||||
|
@ -277,8 +278,23 @@ fn schema_for_struct(fields: &[Field], cattrs: &attr::Container) -> TokenStream
|
||||||
required.push(name.clone());
|
required.push(name.clone());
|
||||||
}
|
}
|
||||||
let ty = get_json_schema_type(field);
|
let ty = get_json_schema_type(field);
|
||||||
quote_spanned! {field.original.span()=>
|
|
||||||
props.insert(#name.to_owned(), gen.subschema_for::<#ty>()?);
|
if field.attrs.skip_deserializing() {
|
||||||
|
quote_spanned! {field.original.span()=>
|
||||||
|
let mut schema: schemars::schema::SchemaObject = gen.subschema_for::<#ty>()?.into();
|
||||||
|
schema.metadata().read_only = true;
|
||||||
|
props.insert(#name.to_owned(), schema.into());
|
||||||
|
}
|
||||||
|
} else if field.attrs.skip_serializing() {
|
||||||
|
quote_spanned! {field.original.span()=>
|
||||||
|
let mut schema: schemars::schema::SchemaObject = gen.subschema_for::<#ty>()?.into();
|
||||||
|
schema.metadata().write_only = true;
|
||||||
|
props.insert(#name.to_owned(), schema.into());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote_spanned! {field.original.span()=>
|
||||||
|
props.insert(#name.to_owned(), gen.subschema_for::<#ty>()?);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue