1use pulumi_gestalt_model::__private::rootcause::{Result, bail};
2use pulumi_gestalt_model::{FromPulumiValue, PulumiValue, ToPulumiValue};
3use serde::{Deserialize, Serialize};
4use std::fmt::Debug;
5
6#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
7#[serde(untagged)]
8pub enum OneOf2<A: Debug, B: Debug> {
9 Left(A),
10 Right(B),
11}
12
13impl<A: Debug, B: Debug> OneOf2<A, B> {
14 pub fn left(a: A) -> Self {
15 OneOf2::Left(a)
16 }
17 pub fn right(b: B) -> Self {
18 OneOf2::Right(b)
19 }
20}
21
22impl<A, B> ToPulumiValue for OneOf2<A, B>
23where
24 A: Debug + ToPulumiValue + Sync,
25 B: Debug + ToPulumiValue + Sync,
26{
27 async fn to_pulumi_value(&self) -> PulumiValue {
28 match self {
29 OneOf2::Left(a) => a.to_pulumi_value().await,
30 OneOf2::Right(b) => b.to_pulumi_value().await,
31 }
32 }
33}
34
35impl<A, B> FromPulumiValue for OneOf2<A, B>
36where
37 A: Debug + FromPulumiValue,
38 B: Debug + FromPulumiValue,
39{
40 fn from_pulumi_value(value: &PulumiValue) -> Result<Self> {
41 match A::from_pulumi_value(value) {
42 Ok(v) => Ok(Self::Left(v)),
43 Err(err_a) => match B::from_pulumi_value(value) {
44 Ok(v) => Ok(Self::Right(v)),
45 Err(err_b) => bail!(
46 "Failed to convert PulumiValue to OneOf2<{}, {}>: left variant failed: {}; right variant failed: {}",
47 std::any::type_name::<A>(),
48 std::any::type_name::<B>(),
49 err_a,
50 err_b
51 ),
52 },
53 }
54 }
55}
56
57#[derive(Debug, Serialize, Deserialize)]
58#[serde(untagged)]
59pub enum OneOf3<A: Debug, B: Debug, C: Debug> {
60 Left(A),
61 Middle(B),
62 Right(C),
63}
64
65impl<A: Debug, B: Debug, C: Debug> OneOf3<A, B, C> {
66 pub fn left(a: A) -> Self {
67 OneOf3::Left(a)
68 }
69 pub fn middle(b: B) -> Self {
70 OneOf3::Middle(b)
71 }
72 pub fn right(c: C) -> Self {
73 OneOf3::Right(c)
74 }
75}
76
77impl<A, B, C> ToPulumiValue for OneOf3<A, B, C>
78where
79 A: Debug + ToPulumiValue + Sync,
80 B: Debug + ToPulumiValue + Sync,
81 C: Debug + ToPulumiValue + Sync,
82{
83 async fn to_pulumi_value(&self) -> PulumiValue {
84 match self {
85 OneOf3::Left(a) => a.to_pulumi_value().await,
86 OneOf3::Middle(b) => b.to_pulumi_value().await,
87 OneOf3::Right(c) => c.to_pulumi_value().await,
88 }
89 }
90}
91
92impl<A, B, C> FromPulumiValue for OneOf3<A, B, C>
93where
94 A: Debug + FromPulumiValue,
95 B: Debug + FromPulumiValue,
96 C: Debug + FromPulumiValue,
97{
98 fn from_pulumi_value(value: &PulumiValue) -> Result<Self> {
99 match A::from_pulumi_value(value) {
100 Ok(v) => Ok(Self::Left(v)),
101 Err(err_a) => match B::from_pulumi_value(value) {
102 Ok(v) => Ok(Self::Middle(v)),
103 Err(err_b) => match C::from_pulumi_value(value) {
104 Ok(v) => Ok(Self::Right(v)),
105 Err(err_c) => bail!(
106 "Failed to convert PulumiValue to OneOf3<{}, {}, {}>: left variant failed: {}; middle variant failed: {}; right variant failed: {}",
107 std::any::type_name::<A>(),
108 std::any::type_name::<B>(),
109 std::any::type_name::<C>(),
110 err_a,
111 err_b,
112 err_c
113 ),
114 },
115 },
116 }
117 }
118}
119
120#[derive(Debug, Serialize, Deserialize)]
121#[serde(untagged)]
122pub enum OneOf4<A: Debug, B: Debug, C: Debug, D: Debug> {
123 Left(A),
124 Middle1(B),
125 Middle2(C),
126 Right(D),
127}
128
129impl<A: Debug, B: Debug, C: Debug, D: Debug> OneOf4<A, B, C, D> {
130 pub fn left(a: A) -> Self {
131 OneOf4::Left(a)
132 }
133 pub fn middle1(b: B) -> Self {
134 OneOf4::Middle1(b)
135 }
136 pub fn middle2(c: C) -> Self {
137 OneOf4::Middle2(c)
138 }
139 pub fn right(d: D) -> Self {
140 OneOf4::Right(d)
141 }
142}
143
144impl<A, B, C, D> ToPulumiValue for OneOf4<A, B, C, D>
145where
146 A: Debug + ToPulumiValue + Sync,
147 B: Debug + ToPulumiValue + Sync,
148 C: Debug + ToPulumiValue + Sync,
149 D: Debug + ToPulumiValue + Sync,
150{
151 async fn to_pulumi_value(&self) -> PulumiValue {
152 match self {
153 OneOf4::Left(a) => a.to_pulumi_value().await,
154 OneOf4::Middle1(b) => b.to_pulumi_value().await,
155 OneOf4::Middle2(c) => c.to_pulumi_value().await,
156 OneOf4::Right(d) => d.to_pulumi_value().await,
157 }
158 }
159}
160
161impl<A, B, C, D> FromPulumiValue for OneOf4<A, B, C, D>
162where
163 A: Debug + FromPulumiValue,
164 B: Debug + FromPulumiValue,
165 C: Debug + FromPulumiValue,
166 D: Debug + FromPulumiValue,
167{
168 fn from_pulumi_value(value: &PulumiValue) -> Result<Self> {
169 match A::from_pulumi_value(value) {
170 Ok(v) => Ok(Self::Left(v)),
171 Err(err_a) => match B::from_pulumi_value(value) {
172 Ok(v) => Ok(Self::Middle1(v)),
173 Err(err_b) => match C::from_pulumi_value(value) {
174 Ok(v) => Ok(Self::Middle2(v)),
175 Err(err_c) => match D::from_pulumi_value(value) {
176 Ok(v) => Ok(Self::Right(v)),
177 Err(err_d) => bail!(
178 "Failed to convert PulumiValue to OneOf4<{}, {}, {}, {}>: left variant failed: {}; middle1 variant failed: {}; middle2 variant failed: {}; right variant failed: {}",
179 std::any::type_name::<A>(),
180 std::any::type_name::<B>(),
181 std::any::type_name::<C>(),
182 std::any::type_name::<D>(),
183 err_a,
184 err_b,
185 err_c,
186 err_d
187 ),
188 },
189 },
190 },
191 }
192 }
193}
194
195#[cfg(test)]
196mod tests {
197 use super::*;
198 use pulumi_gestalt_model::__private::futures::executor::block_on;
199 use pulumi_gestalt_model::PulumiValueContent;
200 use std::collections::HashSet;
201
202 fn string_value(value: &str) -> PulumiValue {
203 PulumiValue {
204 content: PulumiValueContent::String(value.to_string()),
205 secret: false,
206 dependencies: HashSet::new(),
207 }
208 }
209
210 #[test]
211 fn to_pulumi_value_oneof2_uses_active_variant() {
212 let value: OneOf2<i32, String> = OneOf2::right("hello".to_string());
213 let pulumi = block_on(value.to_pulumi_value());
214 assert_eq!(
215 pulumi.content,
216 PulumiValueContent::String("hello".to_string())
217 );
218 }
219
220 #[test]
221 fn to_pulumi_value_oneof3_uses_active_variant() {
222 let value: OneOf3<i32, String, bool> = OneOf3::middle("hello".to_string());
223 let pulumi = block_on(value.to_pulumi_value());
224 assert_eq!(
225 pulumi.content,
226 PulumiValueContent::String("hello".to_string())
227 );
228 }
229
230 #[test]
231 fn to_pulumi_value_oneof4_uses_active_variant() {
232 let value: OneOf4<i32, bool, String, f64> = OneOf4::middle2("hello".to_string());
233 let pulumi = block_on(value.to_pulumi_value());
234 assert_eq!(
235 pulumi.content,
236 PulumiValueContent::String("hello".to_string())
237 );
238 }
239
240 #[test]
241 fn from_pulumi_value_oneof2_success() {
242 let parsed: OneOf2<i32, String> =
243 OneOf2::from_pulumi_value(&string_value("hello")).unwrap();
244 match parsed {
245 OneOf2::Right(value) => assert_eq!(value, "hello"),
246 _ => panic!("Expected Right variant"),
247 }
248 }
249
250 #[test]
251 fn from_pulumi_value_oneof3_success() {
252 let parsed: OneOf3<i32, String, bool> =
253 OneOf3::from_pulumi_value(&string_value("hello")).unwrap();
254 match parsed {
255 OneOf3::Middle(value) => assert_eq!(value, "hello"),
256 _ => panic!("Expected Middle variant"),
257 }
258 }
259
260 #[test]
261 fn from_pulumi_value_oneof4_success() {
262 let parsed: OneOf4<i32, bool, String, f64> =
263 OneOf4::from_pulumi_value(&string_value("hello")).unwrap();
264 match parsed {
265 OneOf4::Middle2(value) => assert_eq!(value, "hello"),
266 _ => panic!("Expected Middle2 variant"),
267 }
268 }
269
270 #[test]
271 fn from_pulumi_value_ambiguous_prefers_left_to_right() {
272 let parsed: OneOf2<String, String> =
273 OneOf2::from_pulumi_value(&string_value("hello")).unwrap();
274 match parsed {
275 OneOf2::Left(value) => assert_eq!(value, "hello"),
276 _ => panic!("Expected Left variant"),
277 }
278 }
279
280 #[test]
281 fn from_pulumi_value_failure_includes_oneof_context() {
282 let value = PulumiValue {
283 content: PulumiValueContent::Boolean(true),
284 secret: false,
285 dependencies: HashSet::new(),
286 };
287
288 let result: Result<OneOf3<i32, String, f64>> = OneOf3::from_pulumi_value(&value);
289 assert!(result.is_err());
290 let message = result.err().unwrap().to_string();
291 assert!(message.contains("Failed to convert PulumiValue to OneOf3"));
292 assert!(message.contains("left variant failed"));
293 assert!(message.contains("middle variant failed"));
294 assert!(message.contains("right variant failed"));
295 }
296}