vld/modifiers/nullable.rs
1use serde_json::Value;
2
3use crate::error::VldError;
4use crate::schema::VldSchema;
5
6/// Wraps a schema to allow null values.
7///
8/// If the value is `null`, returns `Ok(None)`.
9/// Otherwise, delegates to the inner schema and wraps the result in `Some`.
10///
11/// The difference from [`ZOptional`](super::ZOptional) is semantic:
12/// - `optional()`: field can be missing entirely
13/// - `nullable()`: field must be present but can be null
14///
15/// At the `Value` level both behave the same. The distinction matters
16/// when used with the `schema!` macro for object validation.
17pub struct ZNullable<T: VldSchema> {
18 inner: T,
19}
20
21impl<T: VldSchema> ZNullable<T> {
22 pub fn new(inner: T) -> Self {
23 Self { inner }
24 }
25
26 /// Access the inner schema (for JSON Schema generation).
27 pub fn inner_schema(&self) -> &T {
28 &self.inner
29 }
30}
31
32impl<T: VldSchema> VldSchema for ZNullable<T> {
33 type Output = Option<T::Output>;
34
35 fn parse_value(&self, value: &Value) -> Result<Option<T::Output>, VldError> {
36 if value.is_null() {
37 return Ok(None);
38 }
39 self.inner.parse_value(value).map(Some)
40 }
41}