1use serde_json::Value;
2
3use crate::error::{IssueCode, VldError};
4use crate::schema::VldSchema;
5
6#[derive(Debug, Clone, PartialEq)]
8#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
9#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
10pub enum Either<A, B> {
11 Left(A),
12 Right(B),
13}
14
15impl<A, B> Either<A, B> {
16 pub fn is_left(&self) -> bool {
17 matches!(self, Either::Left(_))
18 }
19 pub fn is_right(&self) -> bool {
20 matches!(self, Either::Right(_))
21 }
22 pub fn left(self) -> Option<A> {
23 match self {
24 Either::Left(a) => Some(a),
25 _ => None,
26 }
27 }
28 pub fn right(self) -> Option<B> {
29 match self {
30 Either::Right(b) => Some(b),
31 _ => None,
32 }
33 }
34}
35
36pub struct ZUnion2<A: VldSchema, B: VldSchema> {
40 first: A,
41 second: B,
42}
43
44impl<A: VldSchema, B: VldSchema> ZUnion2<A, B> {
45 pub fn new(first: A, second: B) -> Self {
46 Self { first, second }
47 }
48
49 pub fn schema_a(&self) -> &A {
51 &self.first
52 }
53 pub fn schema_b(&self) -> &B {
55 &self.second
56 }
57}
58
59impl<A: VldSchema, B: VldSchema> VldSchema for ZUnion2<A, B> {
60 type Output = Either<A::Output, B::Output>;
61
62 fn parse_value(&self, value: &Value) -> Result<Self::Output, VldError> {
63 if let Ok(v) = self.first.parse_value(value) {
64 return Ok(Either::Left(v));
65 }
66 if let Ok(v) = self.second.parse_value(value) {
67 return Ok(Either::Right(v));
68 }
69 Err(VldError::single(
70 IssueCode::Custom {
71 code: "invalid_union".to_string(),
72 },
73 "Input did not match any variant of the union",
74 ))
75 }
76}
77
78#[derive(Debug, Clone, PartialEq)]
80#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
81#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
82pub enum Either3<A, B, C> {
83 First(A),
84 Second(B),
85 Third(C),
86}
87
88pub struct ZUnion3<A: VldSchema, B: VldSchema, C: VldSchema> {
92 first: A,
93 second: B,
94 third: C,
95}
96
97impl<A: VldSchema, B: VldSchema, C: VldSchema> ZUnion3<A, B, C> {
98 pub fn new(first: A, second: B, third: C) -> Self {
99 Self {
100 first,
101 second,
102 third,
103 }
104 }
105
106 pub fn schema_a(&self) -> &A {
108 &self.first
109 }
110 pub fn schema_b(&self) -> &B {
112 &self.second
113 }
114 pub fn schema_c(&self) -> &C {
116 &self.third
117 }
118}
119
120impl<A: VldSchema, B: VldSchema, C: VldSchema> VldSchema for ZUnion3<A, B, C> {
121 type Output = Either3<A::Output, B::Output, C::Output>;
122
123 fn parse_value(&self, value: &Value) -> Result<Self::Output, VldError> {
124 if let Ok(v) = self.first.parse_value(value) {
125 return Ok(Either3::First(v));
126 }
127 if let Ok(v) = self.second.parse_value(value) {
128 return Ok(Either3::Second(v));
129 }
130 if let Ok(v) = self.third.parse_value(value) {
131 return Ok(Either3::Third(v));
132 }
133 Err(VldError::single(
134 IssueCode::Custom {
135 code: "invalid_union".to_string(),
136 },
137 "Input did not match any variant of the union",
138 ))
139 }
140}