use serde_json::Value;
use crate::error::{IssueCode, VldError};
use crate::schema::VldSchema;
pub trait DynSchema {
fn dyn_parse(&self, value: &Value) -> Result<Value, VldError>;
#[cfg(feature = "openapi")]
fn dyn_json_schema(&self) -> Value;
#[cfg(feature = "openapi")]
fn dyn_is_required(&self) -> bool;
#[cfg(feature = "openapi")]
fn dyn_collect_nested_schemas(&self, out: &mut Vec<crate::schema::NestedSchemaEntry>);
}
pub(crate) fn to_json_value<T: serde::Serialize + ?Sized>(out: &T) -> Result<Value, VldError> {
serde_json::to_value(out).map_err(|e| {
VldError::from_code(IssueCode::SerializeError {
detail: e.to_string(),
})
})
}
#[cfg(not(feature = "openapi"))]
impl<T> DynSchema for T
where
T: VldSchema,
T::Output: serde::Serialize,
{
fn dyn_parse(&self, value: &Value) -> Result<Value, VldError> {
to_json_value(&self.parse_value(value)?)
}
}
#[cfg(feature = "openapi")]
impl<T> DynSchema for T
where
T: VldSchema + crate::openapi::JsonSchema + crate::openapi::CollectNestedSchemas,
T::Output: serde::Serialize,
{
fn dyn_parse(&self, value: &Value) -> Result<Value, VldError> {
to_json_value(&self.parse_value(value)?)
}
fn dyn_json_schema(&self) -> Value {
self.json_schema()
}
fn dyn_is_required(&self) -> bool {
crate::openapi::JsonSchema::is_required(self)
}
fn dyn_collect_nested_schemas(&self, out: &mut Vec<crate::schema::NestedSchemaEntry>) {
self.collect_nested_schemas(out);
}
}