Add Schema
methods insert
, get
and remove
These are just convenience methods that delegate to the inner object. `insert` will also convert bool schemas to object schemas.
This commit is contained in:
parent
d6c8b6b022
commit
0672c862c8
7 changed files with 109 additions and 76 deletions
|
@ -129,9 +129,7 @@ pub struct MyTransform;
|
|||
impl Transform for MyTransform {
|
||||
fn transform(&mut self, schema: &mut Schema) {
|
||||
// First, make our change to this schema
|
||||
if let Some(obj) = schema.as_object_mut() {
|
||||
obj.insert("my_property".to_string(), serde_json::json!("hello world"));
|
||||
}
|
||||
schema.insert("my_property".to_string(), serde_json::json!("hello world"));
|
||||
|
||||
// Then apply the transform to any subschemas
|
||||
transform_subschemas(self, schema);
|
||||
|
@ -147,9 +145,7 @@ Also, since `Transform` is now implemented for functions that take a single `&mu
|
|||
```rust
|
||||
fn my_transform(schema: &mut Schema) {
|
||||
// First, make our change to this schema
|
||||
if let Some(obj) = schema.as_object_mut() {
|
||||
obj.insert("my_property".to_string(), serde_json::json!("hello world"));
|
||||
}
|
||||
schema.insert("my_property".to_string(), serde_json::json!("hello world"));
|
||||
|
||||
// Then apply the transform to any subschemas
|
||||
transform_subschemas(&mut my_transform, schema);
|
||||
|
@ -165,9 +161,7 @@ Finally, you can also use the `RecursiveTransform` newtype to convert a non-recu
|
|||
|
||||
```rust
|
||||
fn my_transform2(schema: &mut Schema) {
|
||||
if let Some(obj) = schema.as_object_mut() {
|
||||
obj.insert("my_property".to_string(), serde_json::json!("hello world"));
|
||||
}
|
||||
schema.insert("my_property".to_string(), serde_json::json!("hello world"));
|
||||
}
|
||||
|
||||
let mut schema = schemars::schema_for!(str);
|
||||
|
|
|
@ -25,9 +25,7 @@ pub enum MyEnum {
|
|||
}
|
||||
|
||||
fn remove_format(schema: &mut Schema) {
|
||||
if let Some(obj) = schema.as_object_mut() {
|
||||
obj.remove("format");
|
||||
}
|
||||
schema.remove("format");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -25,9 +25,7 @@ pub enum MyEnum {
|
|||
}
|
||||
|
||||
fn remove_format(schema: &mut Schema) {
|
||||
if let Some(obj) = schema.as_object_mut() {
|
||||
obj.remove("format");
|
||||
}
|
||||
schema.remove("format");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -20,9 +20,7 @@ pub fn json_schema_for_flatten<T: ?Sized + JsonSchema>(
|
|||
let mut schema = T::_schemars_private_non_optional_json_schema(generator);
|
||||
|
||||
if T::_schemars_private_is_option() && !required {
|
||||
if let Some(object) = schema.as_object_mut() {
|
||||
object.remove("required");
|
||||
}
|
||||
schema.remove("required");
|
||||
}
|
||||
|
||||
// Always allow aditional/unevaluated properties, because the outer struct determines
|
||||
|
@ -33,16 +31,14 @@ pub fn json_schema_for_flatten<T: ?Sized + JsonSchema>(
|
|||
}
|
||||
|
||||
fn allow_unknown_properties(schema: &mut Schema) {
|
||||
if let Some(obj) = schema.as_object_mut() {
|
||||
if obj.get("additionalProperties").and_then(Value::as_bool) == Some(false) {
|
||||
obj.remove("additionalProperties");
|
||||
if schema.get("additionalProperties").and_then(Value::as_bool) == Some(false) {
|
||||
schema.remove("additionalProperties");
|
||||
}
|
||||
if obj.get("unevaluatedProperties").and_then(Value::as_bool) == Some(false) {
|
||||
obj.remove("unevaluatedProperties");
|
||||
if schema.get("unevaluatedProperties").and_then(Value::as_bool) == Some(false) {
|
||||
schema.remove("unevaluatedProperties");
|
||||
}
|
||||
|
||||
transform_immediate_subschemas(&mut allow_unknown_properties, schema);
|
||||
}
|
||||
}
|
||||
|
||||
/// Hack to simulate specialization:
|
||||
|
@ -211,7 +207,7 @@ pub fn apply_inner_validation(schema: &mut Schema, f: fn(&mut Schema) -> ()) {
|
|||
if let Some(inner_schema) = schema
|
||||
.as_object_mut()
|
||||
.and_then(|o| o.get_mut("items"))
|
||||
.and_then(|i| <&mut Schema>::try_from(i).ok())
|
||||
.and_then(|i| i.try_into().ok())
|
||||
{
|
||||
f(inner_schema);
|
||||
}
|
||||
|
|
|
@ -138,10 +138,80 @@ impl Schema {
|
|||
self.0 = Value::Object(map);
|
||||
}
|
||||
|
||||
self.as_object_mut()
|
||||
self.0
|
||||
.as_object_mut()
|
||||
.expect("Schema value should be of type Object.")
|
||||
}
|
||||
|
||||
/// Inserts a property into the schema, replacing any previous value.
|
||||
///
|
||||
/// If the schema wraps a bool value, it will first be converted into an equivalent object schema.
|
||||
///
|
||||
/// If the schema did not have this key present, `None` is returned.
|
||||
///
|
||||
/// If the schema did have this key present, the value is updated, and the old value is returned.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// use schemars::json_schema;
|
||||
/// use serde_json::json;
|
||||
///
|
||||
/// let mut schema = json_schema!(true);
|
||||
/// assert_eq!(schema.insert("type".to_owned(), "array".into()), None);
|
||||
/// assert_eq!(schema.insert("type".to_owned(), "object".into()), Some(json!("array")));
|
||||
///
|
||||
/// assert_eq!(schema, json_schema!({"type": "object"}));
|
||||
/// ```
|
||||
pub fn insert(&mut self, k: String, v: Value) -> Option<Value> {
|
||||
self.ensure_object().insert(k, v)
|
||||
}
|
||||
|
||||
/// If the `Schema`'s underlying JSON value is an object, gets a reference to that object's value for the given key.
|
||||
///
|
||||
/// This always returns `None` for bool schemas.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// use schemars::json_schema;
|
||||
/// use serde_json::json;
|
||||
///
|
||||
/// let obj_schema = json_schema!({"type": "array"});
|
||||
/// assert_eq!(obj_schema.get("type"), Some(&json!("array")));
|
||||
/// assert_eq!(obj_schema.get("format"), None);
|
||||
///
|
||||
/// let bool_schema = json_schema!(true);
|
||||
/// assert_eq!(bool_schema.get("type"), None);
|
||||
/// ```
|
||||
pub fn get<Q>(&self, key: &Q) -> Option<&Value>
|
||||
where
|
||||
String: core::borrow::Borrow<Q>,
|
||||
Q: ?Sized + Ord + Eq + core::hash::Hash,
|
||||
{
|
||||
self.0.as_object().and_then(|o| o.get(key))
|
||||
}
|
||||
|
||||
/// If the `Schema`'s underlying JSON value is an object, removes and returns its value for the given key.
|
||||
///
|
||||
/// This always returns `None` for bool schemas, without modifying them.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// use schemars::json_schema;
|
||||
/// use serde_json::json;
|
||||
///
|
||||
/// let mut schema = json_schema!({"type": "array"});
|
||||
/// assert_eq!(schema.remove("type"), Some(json!("array")));
|
||||
/// assert_eq!(schema, json_schema!({}));
|
||||
///
|
||||
/// ```
|
||||
pub fn remove<Q>(&mut self, key: &Q) -> Option<Value>
|
||||
where
|
||||
String: core::borrow::Borrow<Q>,
|
||||
Q: ?Sized + Ord + Eq + core::hash::Hash,
|
||||
{
|
||||
self.0.as_object_mut().and_then(|o| o.remove(key))
|
||||
}
|
||||
|
||||
pub(crate) fn has_type(&self, ty: &str) -> bool {
|
||||
match self.0.get("type") {
|
||||
Some(Value::Array(values)) => values.iter().any(|v| v.as_str() == Some(ty)),
|
||||
|
|
|
@ -21,9 +21,7 @@ pub struct MyTransform;
|
|||
impl Transform for MyTransform {
|
||||
fn transform(&mut self, schema: &mut Schema) {
|
||||
// First, make our change to this schema
|
||||
if let Some(obj) = schema.as_object_mut() {
|
||||
obj.insert("my_property".to_string(), serde_json::json!("hello world"));
|
||||
}
|
||||
schema.insert("my_property".to_string(), "hello world".into());
|
||||
|
||||
// Then apply the transform to any subschemas
|
||||
transform_subschemas(self, schema);
|
||||
|
@ -55,9 +53,7 @@ The same example with a `fn` transform:
|
|||
use schemars::transform::transform_subschemas;
|
||||
|
||||
fn add_property(schema: &mut Schema) {
|
||||
if let Some(obj) = schema.as_object_mut() {
|
||||
obj.insert("my_property".to_string(), serde_json::json!("hello world"));
|
||||
}
|
||||
schema.insert("my_property".to_string(), "hello world".into());
|
||||
|
||||
transform_subschemas(&mut add_property, schema)
|
||||
}
|
||||
|
@ -87,9 +83,7 @@ And the same example using a closure wrapped in a `RecursiveTransform`:
|
|||
use schemars::transform::{Transform, RecursiveTransform};
|
||||
|
||||
let mut transform = RecursiveTransform(|schema: &mut Schema| {
|
||||
if let Some(obj) = schema.as_object_mut() {
|
||||
obj.insert("my_property".to_string(), serde_json::json!("hello world"));
|
||||
}
|
||||
schema.insert("my_property".to_string(), "hello world".into());
|
||||
});
|
||||
|
||||
let mut schema = json_schema!({
|
||||
|
@ -236,9 +230,7 @@ pub(crate) fn transform_immediate_subschemas<T: Transform + ?Sized>(
|
|||
/// use schemars::transform::{Transform, RecursiveTransform};
|
||||
///
|
||||
/// let mut transform = RecursiveTransform(|schema: &mut Schema| {
|
||||
/// if let Some(obj) = schema.as_object_mut() {
|
||||
/// obj.insert("my_property".to_string(), serde_json::json!("hello world"));
|
||||
/// }
|
||||
/// schema.insert("my_property".to_string(), "hello world".into());
|
||||
/// });
|
||||
///
|
||||
/// let mut schema = json_schema!({
|
||||
|
@ -289,9 +281,7 @@ impl Transform for ReplaceBoolSchemas {
|
|||
if let Some((ap_key, ap_value)) = obj.remove_entry("additionalProperties") {
|
||||
transform_subschemas(self, schema);
|
||||
|
||||
if let Some(obj) = schema.as_object_mut() {
|
||||
obj.insert(ap_key, ap_value);
|
||||
}
|
||||
schema.insert(ap_key, ap_value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -339,11 +329,9 @@ impl Transform for SetSingleExample {
|
|||
fn transform(&mut self, schema: &mut Schema) {
|
||||
transform_subschemas(self, schema);
|
||||
|
||||
if let Some(obj) = schema.as_object_mut() {
|
||||
if let Some(Value::Array(examples)) = obj.remove("examples") {
|
||||
if let Some(Value::Array(examples)) = schema.remove("examples") {
|
||||
if let Some(first_example) = examples.into_iter().next() {
|
||||
obj.insert("example".into(), first_example);
|
||||
}
|
||||
schema.insert("example".into(), first_example);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -360,10 +348,8 @@ impl Transform for ReplaceConstValue {
|
|||
fn transform(&mut self, schema: &mut Schema) {
|
||||
transform_subschemas(self, schema);
|
||||
|
||||
if let Some(obj) = schema.as_object_mut() {
|
||||
if let Some(value) = obj.remove("const") {
|
||||
obj.insert("enum".into(), Value::Array(vec![value]));
|
||||
}
|
||||
if let Some(value) = schema.remove("const") {
|
||||
schema.insert("enum".into(), Value::Array(vec![value]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -381,13 +367,11 @@ impl Transform for ReplacePrefixItems {
|
|||
fn transform(&mut self, schema: &mut Schema) {
|
||||
transform_subschemas(self, schema);
|
||||
|
||||
if let Some(obj) = schema.as_object_mut() {
|
||||
if let Some(prefix_items) = obj.remove("prefixItems") {
|
||||
let previous_items = obj.insert("items".to_owned(), prefix_items);
|
||||
if let Some(prefix_items) = schema.remove("prefixItems") {
|
||||
let previous_items = schema.insert("items".to_owned(), prefix_items);
|
||||
|
||||
if let Some(previous_items) = previous_items {
|
||||
obj.insert("additionalItems".to_owned(), previous_items);
|
||||
}
|
||||
schema.insert("additionalItems".to_owned(), previous_items);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -400,14 +384,11 @@ impl Transform for ReplaceUnevaluatedProperties {
|
|||
fn transform(&mut self, schema: &mut Schema) {
|
||||
transform_subschemas(self, schema);
|
||||
|
||||
let Some(obj) = schema.as_object_mut() else {
|
||||
return;
|
||||
};
|
||||
let Some(up) = obj.remove("unevaluatedProperties") else {
|
||||
let Some(up) = schema.remove("unevaluatedProperties") else {
|
||||
return;
|
||||
};
|
||||
|
||||
obj.insert("additionalProperties".to_owned(), up);
|
||||
schema.insert("additionalProperties".to_owned(), up);
|
||||
|
||||
let mut gather_property_names = GatherPropertyNames::default();
|
||||
gather_property_names.transform(schema);
|
||||
|
|
|
@ -1,24 +1,20 @@
|
|||
mod util;
|
||||
use schemars::{transform::RecursiveTransform, JsonSchema, Schema};
|
||||
use serde_json::Value;
|
||||
use serde_json::{Map, Value};
|
||||
use util::*;
|
||||
|
||||
fn capitalize_type(schema: &mut Schema) {
|
||||
if let Some(obj) = schema.as_object_mut() {
|
||||
if let Some(Value::String(ty)) = obj.get("type") {
|
||||
obj.insert("upperType".to_owned(), ty.to_uppercase().into());
|
||||
}
|
||||
if let Some(Value::String(ty)) = schema.get("type") {
|
||||
schema.insert("upperType".to_owned(), ty.to_uppercase().into());
|
||||
}
|
||||
}
|
||||
|
||||
fn insert_property_count(schema: &mut Schema) {
|
||||
if let Some(obj) = schema.as_object_mut() {
|
||||
let count = obj
|
||||
let count = schema
|
||||
.get("properties")
|
||||
.and_then(|p| p.as_object())
|
||||
.map_or(0, |p| p.len());
|
||||
obj.insert("propertyCount".to_owned(), count.into());
|
||||
}
|
||||
.and_then(Value::as_object)
|
||||
.map_or(0, Map::len);
|
||||
schema.insert("propertyCount".to_owned(), count.into());
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue