1pub mod json;
11#[cfg(feature = "serde")]
12mod serialization;
13pub mod yaml;
14
15#[cfg(feature = "serde")]
16pub use serialization::*;
17
18use std::fmt;
19
20#[derive(Debug)]
22pub enum Error {
23 FailedParsingYaml(std::path::PathBuf),
24 UnexpectedDataType,
25 MissingField,
26 FileIo(std::io::Error, std::path::PathBuf),
27}
28
29impl fmt::Display for Error {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 match self {
32 Error::FailedParsingYaml(p) => {
33 f.write_str(format!("Failed parsing the YAML from {:?}", p.display()).as_str())
34 }
35 Error::UnexpectedDataType => {
36 f.write_str("The present data type wasn't what was expected")
37 }
38 Error::MissingField => f.write_str("A required field was missing"),
39 Error::FileIo(e, p) => {
40 f.write_str(format!("File error for {:?}: {}", p.display(), e).as_str())
41 }
42 }
43 }
44}
45
46impl std::error::Error for Error {}
47
48#[derive(Debug, Clone, PartialEq, PartialOrd)]
71pub enum Content {
72 Bool(bool),
73
74 U8(u8),
75 U16(u16),
76 U32(u32),
77 U64(u64),
78 U128(u128),
79
80 I8(i8),
81 I16(i16),
82 I32(i32),
83 I64(i64),
84 I128(i128),
85
86 F32(f32),
87 F64(f64),
88
89 Char(char),
90 String(String),
91 Bytes(Vec<u8>),
92
93 #[doc(hidden)]
94 None,
95 #[doc(hidden)]
96 Some(Box<Content>),
97
98 #[doc(hidden)]
99 Unit,
100 #[doc(hidden)]
101 UnitStruct(&'static str),
102 #[doc(hidden)]
103 UnitVariant(&'static str, u32, &'static str),
104 #[doc(hidden)]
105 NewtypeStruct(&'static str, Box<Content>),
106 #[doc(hidden)]
107 NewtypeVariant(&'static str, u32, &'static str, Box<Content>),
108
109 Seq(Vec<Content>),
110 #[doc(hidden)]
111 Tuple(Vec<Content>),
112 #[doc(hidden)]
113 TupleStruct(&'static str, Vec<Content>),
114 #[doc(hidden)]
115 TupleVariant(&'static str, u32, &'static str, Vec<Content>),
116 Map(Vec<(Content, Content)>),
117 #[doc(hidden)]
118 Struct(&'static str, Vec<(&'static str, Content)>),
119 #[doc(hidden)]
120 StructVariant(
121 &'static str,
122 u32,
123 &'static str,
124 Vec<(&'static str, Content)>,
125 ),
126}
127
128macro_rules! impl_from {
129 ($ty:ty, $newty:ident) => {
130 impl From<$ty> for Content {
131 fn from(value: $ty) -> Content {
132 Content::$newty(value)
133 }
134 }
135 };
136}
137
138impl_from!(bool, Bool);
139impl_from!(u8, U8);
140impl_from!(u16, U16);
141impl_from!(u32, U32);
142impl_from!(u64, U64);
143impl_from!(u128, U128);
144impl_from!(i8, I8);
145impl_from!(i16, I16);
146impl_from!(i32, I32);
147impl_from!(i64, I64);
148impl_from!(i128, I128);
149impl_from!(f32, F32);
150impl_from!(f64, F64);
151impl_from!(char, Char);
152impl_from!(String, String);
153impl_from!(Vec<u8>, Bytes);
154
155impl From<()> for Content {
156 fn from(_value: ()) -> Content {
157 Content::Unit
158 }
159}
160
161impl<'a> From<&'a str> for Content {
162 fn from(value: &'a str) -> Content {
163 Content::String(value.to_string())
164 }
165}
166
167impl<'a> From<&'a [u8]> for Content {
168 fn from(value: &'a [u8]) -> Content {
169 Content::Bytes(value.to_vec())
170 }
171}
172
173impl Content {
174 pub fn resolve_inner(&self) -> &Content {
187 match *self {
188 Content::Some(ref v)
189 | Content::NewtypeStruct(_, ref v)
190 | Content::NewtypeVariant(_, _, _, ref v) => v.resolve_inner(),
191 ref other => other,
192 }
193 }
194
195 pub fn resolve_inner_mut(&mut self) -> &mut Content {
197 match *self {
198 Content::Some(ref mut v)
199 | Content::NewtypeStruct(_, ref mut v)
200 | Content::NewtypeVariant(_, _, _, ref mut v) => v.resolve_inner_mut(),
201 ref mut other => other,
202 }
203 }
204
205 pub fn as_str(&self) -> Option<&str> {
207 match self.resolve_inner() {
208 Content::String(ref s) => Some(s.as_str()),
209 _ => None,
210 }
211 }
212
213 pub fn as_bytes(&self) -> Option<&[u8]> {
215 match self.resolve_inner() {
216 Content::Bytes(ref b) => Some(b),
217 _ => None,
218 }
219 }
220
221 pub fn as_slice(&self) -> Option<&[Content]> {
223 match self.resolve_inner() {
224 Content::Seq(ref v) | Content::Tuple(ref v) | Content::TupleVariant(_, _, _, ref v) => {
225 Some(&v[..])
226 }
227 _ => None,
228 }
229 }
230
231 pub fn is_nil(&self) -> bool {
233 matches!(self.resolve_inner(), Content::None | Content::Unit)
234 }
235
236 pub fn as_bool(&self) -> Option<bool> {
238 match *self.resolve_inner() {
239 Content::Bool(val) => Some(val),
240 _ => None,
241 }
242 }
243
244 pub fn as_u64(&self) -> Option<u64> {
246 match *self.resolve_inner() {
247 Content::U8(v) => Some(u64::from(v)),
248 Content::U16(v) => Some(u64::from(v)),
249 Content::U32(v) => Some(u64::from(v)),
250 Content::U64(v) => Some(v),
251 Content::U128(v) => {
252 let rv = v as u64;
253 if rv as u128 == v {
254 Some(rv)
255 } else {
256 None
257 }
258 }
259 Content::I8(v) if v >= 0 => Some(v as u64),
260 Content::I16(v) if v >= 0 => Some(v as u64),
261 Content::I32(v) if v >= 0 => Some(v as u64),
262 Content::I64(v) if v >= 0 => Some(v as u64),
263 Content::I128(v) => {
264 let rv = v as u64;
265 if rv as i128 == v {
266 Some(rv)
267 } else {
268 None
269 }
270 }
271 _ => None,
272 }
273 }
274
275 pub fn as_u128(&self) -> Option<u128> {
277 match *self.resolve_inner() {
278 Content::U128(v) => Some(v),
279 Content::I128(v) if v >= 0 => Some(v as u128),
280 _ => self.as_u64().map(u128::from),
281 }
282 }
283
284 pub fn as_i64(&self) -> Option<i64> {
286 match *self.resolve_inner() {
287 Content::U8(v) => Some(i64::from(v)),
288 Content::U16(v) => Some(i64::from(v)),
289 Content::U32(v) => Some(i64::from(v)),
290 Content::U64(v) => {
291 let rv = v as i64;
292 if rv as u64 == v {
293 Some(rv)
294 } else {
295 None
296 }
297 }
298 Content::U128(v) => {
299 let rv = v as i64;
300 if rv as u128 == v {
301 Some(rv)
302 } else {
303 None
304 }
305 }
306 Content::I8(v) => Some(i64::from(v)),
307 Content::I16(v) => Some(i64::from(v)),
308 Content::I32(v) => Some(i64::from(v)),
309 Content::I64(v) => Some(v),
310 Content::I128(v) => {
311 let rv = v as i64;
312 if rv as i128 == v {
313 Some(rv)
314 } else {
315 None
316 }
317 }
318 _ => None,
319 }
320 }
321
322 pub fn as_i128(&self) -> Option<i128> {
324 match *self.resolve_inner() {
325 Content::U128(v) => {
326 let rv = v as i128;
327 if rv as u128 == v {
328 Some(rv)
329 } else {
330 None
331 }
332 }
333 Content::I128(v) => Some(v),
334 _ => self.as_i64().map(i128::from),
335 }
336 }
337
338 pub fn as_f64(&self) -> Option<f64> {
340 match *self.resolve_inner() {
341 Content::F32(v) => Some(f64::from(v)),
342 Content::F64(v) => Some(v),
343 _ => None,
344 }
345 }
346
347 pub fn walk<F: FnMut(&mut Content) -> bool>(&mut self, visit: &mut F) {
351 if !visit(self) {
352 return;
353 }
354
355 match *self {
356 Content::Some(ref mut inner) => {
357 Self::walk(&mut *inner, visit);
358 }
359 Content::NewtypeStruct(_, ref mut inner) => {
360 Self::walk(&mut *inner, visit);
361 }
362 Content::NewtypeVariant(_, _, _, ref mut inner) => {
363 Self::walk(&mut *inner, visit);
364 }
365 Content::Seq(ref mut vec) => {
366 for inner in vec.iter_mut() {
367 Self::walk(inner, visit);
368 }
369 }
370 Content::Map(ref mut vec) => {
371 for inner in vec.iter_mut() {
372 Self::walk(&mut inner.0, visit);
373 Self::walk(&mut inner.1, visit);
374 }
375 }
376 Content::Struct(_, ref mut vec) => {
377 for inner in vec.iter_mut() {
378 Self::walk(&mut inner.1, visit);
379 }
380 }
381 Content::StructVariant(_, _, _, ref mut vec) => {
382 for inner in vec.iter_mut() {
383 Self::walk(&mut inner.1, visit);
384 }
385 }
386 Content::Tuple(ref mut vec) => {
387 for inner in vec.iter_mut() {
388 Self::walk(inner, visit);
389 }
390 }
391 Content::TupleStruct(_, ref mut vec) => {
392 for inner in vec.iter_mut() {
393 Self::walk(inner, visit);
394 }
395 }
396 Content::TupleVariant(_, _, _, ref mut vec) => {
397 for inner in vec.iter_mut() {
398 Self::walk(inner, visit);
399 }
400 }
401 _ => {}
402 }
403 }
404}