compose_yml/v2/
true_or_struct.rs1use serde::de::{self, Deserialize, Deserializer};
5use serde::ser::{Serialize, Serializer};
6use std::fmt;
7use std::marker::PhantomData;
8
9pub fn deserialize_true_or_struct<'de, T, D>(d: D) -> Result<T, D::Error>
15where
16 T: Deserialize<'de> + Default,
17 D: Deserializer<'de>,
18{
19 struct TrueOrStruct<T>(PhantomData<T>);
21
22 impl<'de, T> de::Visitor<'de> for TrueOrStruct<T>
23 where
24 T: Deserialize<'de> + Default,
25 {
26 type Value = T;
27
28 fn visit_bool<E>(self, value: bool) -> Result<T, E>
29 where
30 E: de::Error,
31 {
32 if value {
33 Ok(Default::default())
34 } else {
35 Err(de::Error::custom(
36 "expected true or struct, got false".to_owned(),
37 ))
38 }
39 }
40
41 fn visit_map<M>(self, visitor: M) -> Result<T, M::Error>
42 where
43 M: de::MapAccess<'de>,
44 {
45 let mvd = de::value::MapAccessDeserializer::new(visitor);
46 Deserialize::deserialize(mvd)
47 }
48
49 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
50 write!(formatter, "a map or a boolean")
51 }
52 }
53
54 d.deserialize_any(TrueOrStruct(PhantomData))
55}
56
57pub fn deserialize_opt_true_or_struct<'de, T, D>(d: D) -> Result<Option<T>, D::Error>
63where
64 T: Deserialize<'de> + Default,
65 D: Deserializer<'de>,
66{
67 struct OptTrueOrStruct<T>(PhantomData<T>);
69
70 impl<'de, T> de::Visitor<'de> for OptTrueOrStruct<T>
71 where
72 T: Deserialize<'de> + Default,
73 {
74 type Value = Option<T>;
75
76 fn visit_none<E>(self) -> Result<Self::Value, E>
77 where
78 E: de::Error,
79 {
80 Ok(None)
81 }
82
83 fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
84 where
85 D: Deserializer<'de>,
86 {
87 deserialize_true_or_struct(deserializer).map(Some)
88 }
89
90 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
91 write!(formatter, "a map or a list of strings")
92 }
93 }
94
95 d.deserialize_option(OptTrueOrStruct(PhantomData))
96}
97
98pub fn serialize_true_or_struct<T, S>(
101 value: &T,
102 serializer: S,
103) -> Result<S::Ok, S::Error>
104where
105 T: Serialize + Default + Eq,
106 S: Serializer,
107{
108 if value == &Default::default() {
109 serializer.serialize_bool(true)
110 } else {
111 value.serialize(serializer)
112 }
113}
114
115pub fn serialize_opt_true_or_struct<T, S>(
120 value: &Option<T>,
121 serializer: S,
122) -> Result<S::Ok, S::Error>
123where
124 T: Serialize + Default + Eq,
125 S: Serializer,
126{
127 struct Wrap<'a, T>(&'a T)
134 where
135 T: Serialize + Default + Eq;
136
137 impl<'a, T> Serialize for Wrap<'a, T>
138 where
139 T: 'a + Serialize + Default + Eq,
140 {
141 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
142 where
143 S: Serializer,
144 {
145 match *self {
146 Wrap(v) => serialize_true_or_struct(v, serializer),
147 }
148 }
149 }
150
151 match *value {
152 None => serializer.serialize_none(),
153 Some(ref v) => serializer.serialize_some(&Wrap(v)),
154 }
155}