#[doc(hidden)]
#[macro_export]
macro_rules! __vld_resolve_key {
($default:expr) => {
$default
};
($default:expr, $override:expr) => {
$override
};
}
#[macro_export]
macro_rules! schema {
(
$(#[$meta:meta])*
$vis:vis struct $name:ident {
$(
$(#[$field_meta:meta])*
$field_vis:vis $field_name:ident : $field_type:ty $(as $rename:literal)? => $schema:expr
),* $(,)?
}
) => {
$(#[$meta])*
$vis struct $name {
$(
$(#[$field_meta])*
$field_vis $field_name: $field_type,
)*
}
impl $name {
pub fn parse<__VldInputT: $crate::input::VldInput + ?Sized>(
input: &__VldInputT,
) -> ::std::result::Result<$name, $crate::error::VldError> {
let __vld_json = <__VldInputT as $crate::input::VldInput>::to_json_value(input)?;
Self::parse_value(&__vld_json)
}
pub fn parse_value(
__vld_json: &$crate::serde_json::Value,
) -> ::std::result::Result<$name, $crate::error::VldError> {
use $crate::schema::VldSchema as _;
let __vld_obj = __vld_json.as_object().ok_or_else(|| {
$crate::error::VldError::single(
$crate::error::IssueCode::InvalidType {
expected: ::std::string::String::from("object"),
received: $crate::error::value_type_name(__vld_json),
},
::std::format!(
"Expected object, received {}",
$crate::error::value_type_name(__vld_json)
),
)
})?;
let mut __vld_errors = $crate::error::VldError::new();
$(
#[allow(non_snake_case)]
let $field_name: ::std::option::Option<$field_type> = {
let __vld_field_schema = $schema;
let __vld_key = $crate::__vld_resolve_key!(
stringify!($field_name) $(, $rename)?
);
let __vld_field_value = __vld_obj
.get(__vld_key)
.unwrap_or(&$crate::serde_json::Value::Null);
match __vld_field_schema.parse_value(__vld_field_value) {
::std::result::Result::Ok(v) => ::std::option::Option::Some(v),
::std::result::Result::Err(e) => {
__vld_errors = $crate::error::VldError::merge(
__vld_errors,
$crate::error::VldError::with_prefix(
e,
$crate::error::PathSegment::Field(
::std::string::String::from(__vld_key),
),
),
);
::std::option::Option::None
}
}
};
)*
if !$crate::error::VldError::is_empty(&__vld_errors) {
return ::std::result::Result::Err(__vld_errors);
}
::std::result::Result::Ok($name {
$(
$field_name: $field_name.unwrap(),
)*
})
}
}
impl $crate::schema::VldParse for $name {
fn vld_parse_value(
value: &$crate::serde_json::Value,
) -> ::std::result::Result<Self, $crate::error::VldError> {
Self::parse_value(value)
}
}
$crate::__vld_if_serialize! {
impl $name {
pub fn validate<__VldT: $crate::serde::Serialize>(
instance: &__VldT,
) -> ::std::result::Result<(), $crate::error::VldError> {
let __vld_json = $crate::serde_json::to_value(instance).map_err(|e| {
$crate::error::VldError::single(
$crate::error::IssueCode::ParseError,
::std::format!("Serialization error: {}", e),
)
})?;
let _ = Self::parse_value(&__vld_json)?;
::std::result::Result::Ok(())
}
pub fn is_valid<__VldT: $crate::serde::Serialize>(instance: &__VldT) -> bool {
Self::validate(instance).is_ok()
}
}
}
$crate::__vld_if_openapi! {
impl $name {
pub fn json_schema() -> $crate::serde_json::Value {
use $crate::json_schema::JsonSchema as _;
let mut __vld_properties = $crate::serde_json::Map::new();
let mut __vld_required: ::std::vec::Vec<::std::string::String> =
::std::vec::Vec::new();
$(
{
let __vld_field_schema = $schema;
let __vld_key = $crate::__vld_resolve_key!(
stringify!($field_name) $(, $rename)?
);
__vld_properties.insert(
::std::string::String::from(__vld_key),
__vld_field_schema.json_schema(),
);
__vld_required.push(
::std::string::String::from(__vld_key),
);
}
)*
$crate::serde_json::json!({
"type": "object",
"required": __vld_required,
"properties": $crate::serde_json::Value::Object(__vld_properties),
})
}
pub fn to_openapi_document() -> $crate::serde_json::Value {
$crate::json_schema::to_openapi_document(stringify!($name), &Self::json_schema())
}
#[doc(hidden)]
pub fn __vld_nested_schemas()
-> ::std::vec::Vec<$crate::json_schema::NestedSchemaEntry>
{
use $crate::json_schema::CollectNestedSchemas as _;
let mut __vld_out: ::std::vec::Vec<$crate::json_schema::NestedSchemaEntry> =
::std::vec::Vec::new();
$(
{
let __vld_field_schema = $schema;
__vld_field_schema.collect_nested_schemas(&mut __vld_out);
}
)*
__vld_out
}
}
}
};
}
#[macro_export]
macro_rules! impl_validate_fields {
(
$name:ident {
$( $field_name:ident : $field_type:ty $(as $rename:literal)? => $schema:expr ),* $(,)?
}
) => {
impl $name {
pub fn validate_fields<__VldInputT: $crate::input::VldInput + ?Sized>(
input: &__VldInputT,
) -> ::std::result::Result<
::std::vec::Vec<$crate::error::FieldResult>,
$crate::error::VldError,
> {
let __vld_json = <__VldInputT as $crate::input::VldInput>::to_json_value(input)?;
Self::validate_fields_value(&__vld_json)
}
pub fn validate_fields_value(
__vld_json: &$crate::serde_json::Value,
) -> ::std::result::Result<
::std::vec::Vec<$crate::error::FieldResult>,
$crate::error::VldError,
> {
let __vld_obj = __vld_json.as_object().ok_or_else(|| {
$crate::error::VldError::single(
$crate::error::IssueCode::InvalidType {
expected: ::std::string::String::from("object"),
received: $crate::error::value_type_name(__vld_json),
},
::std::format!(
"Expected object, received {}",
$crate::error::value_type_name(__vld_json)
),
)
})?;
let mut __vld_results: ::std::vec::Vec<$crate::error::FieldResult> =
::std::vec::Vec::new();
$(
{
let __vld_field_schema = $schema;
let __vld_key = $crate::__vld_resolve_key!(
stringify!($field_name) $(, $rename)?
);
let __vld_field_value = __vld_obj
.get(__vld_key)
.unwrap_or(&$crate::serde_json::Value::Null);
let __vld_result = $crate::object::DynSchema::dyn_parse(
&__vld_field_schema,
__vld_field_value,
);
__vld_results.push($crate::error::FieldResult {
name: ::std::string::String::from(__vld_key),
input: __vld_field_value.clone(),
result: __vld_result,
});
}
)*
::std::result::Result::Ok(__vld_results)
}
pub fn parse_lenient<__VldInputT: $crate::input::VldInput + ?Sized>(
input: &__VldInputT,
) -> ::std::result::Result<
$crate::error::ParseResult<$name>,
$crate::error::VldError,
> {
let __vld_json = <__VldInputT as $crate::input::VldInput>::to_json_value(input)?;
Self::parse_lenient_value(&__vld_json)
}
pub fn parse_lenient_value(
__vld_json: &$crate::serde_json::Value,
) -> ::std::result::Result<
$crate::error::ParseResult<$name>,
$crate::error::VldError,
> {
use $crate::schema::VldSchema as _;
let __vld_obj = __vld_json.as_object().ok_or_else(|| {
$crate::error::VldError::single(
$crate::error::IssueCode::InvalidType {
expected: ::std::string::String::from("object"),
received: $crate::error::value_type_name(__vld_json),
},
::std::format!(
"Expected object, received {}",
$crate::error::value_type_name(__vld_json)
),
)
})?;
let mut __vld_results: ::std::vec::Vec<$crate::error::FieldResult> =
::std::vec::Vec::new();
$(
#[allow(non_snake_case)]
let $field_name: $field_type = {
let __vld_field_schema = $schema;
let __vld_key = $crate::__vld_resolve_key!(
stringify!($field_name) $(, $rename)?
);
let __vld_field_value = __vld_obj
.get(__vld_key)
.unwrap_or(&$crate::serde_json::Value::Null);
match __vld_field_schema.parse_value(__vld_field_value) {
::std::result::Result::Ok(v) => {
let __json_repr = $crate::serde_json::to_value(&v)
.unwrap_or_else(|_| __vld_field_value.clone());
__vld_results.push($crate::error::FieldResult {
name: ::std::string::String::from(__vld_key),
input: __vld_field_value.clone(),
result: ::std::result::Result::Ok(__json_repr),
});
v
}
::std::result::Result::Err(e) => {
__vld_results.push($crate::error::FieldResult {
name: ::std::string::String::from(__vld_key),
input: __vld_field_value.clone(),
result: ::std::result::Result::Err(e),
});
<$field_type as ::std::default::Default>::default()
}
}
};
)*
let __vld_struct = $name {
$( $field_name, )*
};
::std::result::Result::Ok(
$crate::error::ParseResult::new(__vld_struct, __vld_results)
)
}
}
};
}
#[macro_export]
macro_rules! schema_validated {
(
$(#[$meta:meta])*
$vis:vis struct $name:ident {
$(
$(#[$field_meta:meta])*
$field_vis:vis $field_name:ident : $field_type:ty $(as $rename:literal)? => $schema:expr
),* $(,)?
}
) => {
$crate::schema! {
$(#[$meta])*
$vis struct $name {
$(
$(#[$field_meta])*
$field_vis $field_name : $field_type $(as $rename)? => $schema
),*
}
}
$crate::impl_validate_fields!($name {
$( $field_name : $field_type $(as $rename)? => $schema ),*
});
};
}
#[macro_export]
macro_rules! impl_rules {
(
$name:ident {
$( $field:ident => $schema:expr ),* $(,)?
}
) => {
impl $name {
pub fn validate(&self) -> ::std::result::Result<(), $crate::error::VldError> {
use $crate::schema::VldSchema as _;
let mut __vld_errors = $crate::error::VldError::new();
$(
{
let __vld_field_json = $crate::serde_json::to_value(&self.$field)
.map_err(|e| {
$crate::error::VldError::single(
$crate::error::IssueCode::ParseError,
::std::format!(
"Serialization error for field '{}': {}",
stringify!($field), e
),
)
});
match __vld_field_json {
::std::result::Result::Ok(ref __vld_val) => {
let __vld_field_schema = $schema;
if let ::std::result::Result::Err(e) =
__vld_field_schema.parse_value(__vld_val)
{
__vld_errors = $crate::error::VldError::merge(
__vld_errors,
$crate::error::VldError::with_prefix(
e,
$crate::error::PathSegment::Field(
::std::string::String::from(stringify!($field)),
),
),
);
}
}
::std::result::Result::Err(e) => {
__vld_errors = $crate::error::VldError::merge(
__vld_errors,
$crate::error::VldError::with_prefix(
e,
$crate::error::PathSegment::Field(
::std::string::String::from(stringify!($field)),
),
),
);
}
}
}
)*
if __vld_errors.is_empty() {
::std::result::Result::Ok(())
} else {
::std::result::Result::Err(__vld_errors)
}
}
pub fn is_valid(&self) -> bool {
self.validate().is_ok()
}
}
};
}
#[macro_export]
macro_rules! impl_default {
($name:ident { $($field:ident),* $(,)? }) => {
impl ::std::default::Default for $name {
fn default() -> Self {
Self {
$( $field: ::std::default::Default::default(), )*
}
}
}
};
}
#[macro_export]
macro_rules! union {
($a:expr, $b:expr $(,)?) => {
$crate::union($a, $b)
};
($a:expr, $b:expr, $c:expr $(,)?) => {
$crate::union3($a, $b, $c)
};
($a:expr, $b:expr, $c:expr, $d:expr $(,)?) => {
$crate::union($crate::union($a, $b), $crate::union($c, $d))
};
($a:expr, $b:expr, $c:expr, $d:expr, $e:expr $(,)?) => {
$crate::union($crate::union3($a, $b, $c), $crate::union($d, $e))
};
($a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $f:expr $(,)?) => {
$crate::union($crate::union3($a, $b, $c), $crate::union3($d, $e, $f))
};
}