schemars/
_private.rs

1use crate::flatten::Merge;
2use crate::gen::SchemaGenerator;
3use crate::schema::{Metadata, Schema, SchemaObject};
4use crate::JsonSchema;
5use serde::Serialize;
6use serde_json::Value;
7
8// Helper for generating schemas for flattened `Option` fields.
9pub fn json_schema_for_flatten<T: ?Sized + JsonSchema>(
10    gen: &mut SchemaGenerator,
11    required: bool,
12) -> Schema {
13    let mut schema = T::_schemars_private_non_optional_json_schema(gen);
14
15    if T::_schemars_private_is_option() && !required {
16        if let Schema::Object(SchemaObject {
17            object: Some(ref mut object_validation),
18            ..
19        }) = schema
20        {
21            object_validation.required.clear();
22        }
23    }
24
25    schema
26}
27
28pub fn apply_metadata(schema: Schema, metadata: Metadata) -> Schema {
29    if metadata == Metadata::default() {
30        schema
31    } else {
32        let mut schema_obj = schema.into_object();
33        schema_obj.metadata = Some(Box::new(metadata)).merge(schema_obj.metadata);
34        Schema::Object(schema_obj)
35    }
36}
37
38/// Hack to simulate specialization:
39/// `MaybeSerializeWrapper(x).maybe_to_value()` will resolve to either
40/// - The inherent method `MaybeSerializeWrapper::maybe_to_value(...)` if x is `Serialize`
41/// - The trait method `NoSerialize::maybe_to_value(...)` from the blanket impl otherwise
42#[doc(hidden)]
43#[macro_export]
44macro_rules! _schemars_maybe_to_value {
45    ($expression:expr) => {{
46        #[allow(unused_imports)]
47        use $crate::_private::{MaybeSerializeWrapper, NoSerialize as _};
48
49        MaybeSerializeWrapper($expression).maybe_to_value()
50    }};
51}
52
53pub struct MaybeSerializeWrapper<T>(pub T);
54
55pub trait NoSerialize: Sized {
56    fn maybe_to_value(self) -> Option<Value> {
57        None
58    }
59}
60
61impl<T> NoSerialize for T {}
62
63impl<T: Serialize> MaybeSerializeWrapper<T> {
64    pub fn maybe_to_value(self) -> Option<Value> {
65        serde_json::value::to_value(self.0).ok()
66    }
67}