vld/combinators/
transform.rs1use serde_json::Value;
2use std::marker::PhantomData;
3
4use crate::error::VldError;
5use crate::schema::VldSchema;
6
7pub struct ZTransform<T, F, U>
19where
20 T: VldSchema,
21 F: Fn(T::Output) -> U,
22{
23 inner: T,
24 transform_fn: F,
25 _phantom: PhantomData<U>,
26}
27
28impl<T, F, U> ZTransform<T, F, U>
29where
30 T: VldSchema,
31 F: Fn(T::Output) -> U,
32{
33 pub fn new(inner: T, transform_fn: F) -> Self {
35 Self {
36 inner,
37 transform_fn,
38 _phantom: PhantomData,
39 }
40 }
41
42 pub fn inner_schema(&self) -> &T {
44 &self.inner
45 }
46}
47
48impl<T, F, U> VldSchema for ZTransform<T, F, U>
49where
50 T: VldSchema,
51 F: Fn(T::Output) -> U,
52{
53 type Output = U;
54
55 fn parse_value(&self, value: &Value) -> Result<U, VldError> {
56 Ok((self.transform_fn)(self.inner.parse_value(value)?))
57 }
58 fn parse_missing(&self) -> Result<U, VldError> {
59 Ok((self.transform_fn)(self.inner.parse_missing()?))
60 }
61}
62
63pub struct ZTryTransform<T, F, U> {
79 inner: T,
80 transform_fn: F,
81 _phantom: PhantomData<U>,
82}
83
84impl<T, F, U> ZTryTransform<T, F, U> {
85 pub fn new(inner: T, transform_fn: F) -> Self {
87 Self {
88 inner,
89 transform_fn,
90 _phantom: PhantomData,
91 }
92 }
93
94 pub fn inner_schema(&self) -> &T {
96 &self.inner
97 }
98}
99
100impl<T, F, U, E> ZTryTransform<T, F, U>
101where
102 T: VldSchema,
103 F: Fn(T::Output) -> Result<U, E>,
104 E: std::fmt::Display,
105{
106 fn apply(&self, out: T::Output) -> Result<U, VldError> {
107 (self.transform_fn)(out).map_err(|e| {
108 VldError::single(
109 crate::error::IssueCode::Custom {
110 code: "transform".to_string(),
111 },
112 e.to_string(),
113 )
114 })
115 }
116}
117
118impl<T, F, U, E> VldSchema for ZTryTransform<T, F, U>
119where
120 T: VldSchema,
121 F: Fn(T::Output) -> Result<U, E>,
122 E: std::fmt::Display,
123{
124 type Output = U;
125
126 fn parse_value(&self, value: &Value) -> Result<U, VldError> {
127 self.apply(self.inner.parse_value(value)?)
128 }
129 fn parse_missing(&self) -> Result<U, VldError> {
130 self.apply(self.inner.parse_missing()?)
131 }
132}