1mod emitter;
51mod parser;
52
53use std::fmt;
54
55pub use parser::YamlError;
56
57#[derive(Clone, Debug, Default, PartialEq)]
64pub struct Mapping {
65 entries: Vec<(Value, Value)>,
66}
67
68impl Mapping {
69 #[must_use]
71 pub const fn new() -> Self {
72 Self {
73 entries: Vec::new(),
74 }
75 }
76
77 #[must_use]
79 pub const fn len(&self) -> usize {
80 self.entries.len()
81 }
82
83 #[must_use]
85 pub const fn is_empty(&self) -> bool {
86 self.entries.is_empty()
87 }
88
89 #[must_use]
91 pub fn get(&self, key: &str) -> Option<&Value> {
92 self.entries
93 .iter()
94 .find(|(k, _)| k.as_str() == Some(key))
95 .map(|(_, v)| v)
96 }
97
98 pub fn get_mut(&mut self, key: &str) -> Option<&mut Value> {
100 self.entries
101 .iter_mut()
102 .find(|(k, _)| k.as_str() == Some(key))
103 .map(|(_, v)| v)
104 }
105
106 #[must_use]
108 pub fn contains_key(&self, key: &str) -> bool {
109 self.get(key).is_some()
110 }
111
112 pub fn insert(&mut self, key: impl Into<String>, value: Value) -> Option<Value> {
115 let key = key.into();
116 if let Some(slot) = self
117 .entries
118 .iter_mut()
119 .find(|(k, _)| k.as_str() == Some(&key))
120 {
121 return Some(std::mem::replace(&mut slot.1, value));
122 }
123 self.entries.push((Value::String(key), value));
124 None
125 }
126
127 pub fn remove(&mut self, key: &str) -> Option<Value> {
129 let idx = self
130 .entries
131 .iter()
132 .position(|(k, _)| k.as_str() == Some(key))?;
133 Some(self.entries.remove(idx).1)
134 }
135
136 pub(crate) fn push_raw(&mut self, key: Value, value: Value) {
138 self.entries.push((key, value));
139 }
140
141 pub fn iter(&self) -> impl Iterator<Item = (&Value, &Value)> {
143 self.entries.iter().map(|(k, v)| (k, v))
144 }
145
146 pub fn iter_mut(&mut self) -> impl Iterator<Item = (&mut Value, &mut Value)> {
148 self.entries.iter_mut().map(|(k, v)| (k, v))
149 }
150
151 pub fn keys(&self) -> impl Iterator<Item = &str> {
153 self.entries.iter().filter_map(|(k, _)| k.as_str())
154 }
155
156 pub fn values(&self) -> impl Iterator<Item = &Value> {
158 self.entries.iter().map(|(_, v)| v)
159 }
160
161 #[must_use]
163 pub fn entries(&self) -> &[(Value, Value)] {
164 &self.entries
165 }
166}
167
168#[derive(Clone, Debug, PartialEq)]
170pub enum Value {
171 Null,
173 Bool(bool),
175 Int(i64),
177 Float(f64),
179 String(String),
181 Sequence(Vec<Self>),
183 Mapping(Mapping),
185}
186
187impl Value {
188 pub fn parse(text: &str) -> Result<Self, YamlError> {
195 parser::parse(text)
196 }
197
198 #[must_use]
200 pub fn to_yaml_string(&self) -> String {
201 emitter::emit(self)
202 }
203
204 #[must_use]
206 pub fn as_str(&self) -> Option<&str> {
207 match self {
208 Self::String(s) => Some(s),
209 _ => None,
210 }
211 }
212
213 #[must_use]
215 pub const fn as_bool(&self) -> Option<bool> {
216 match self {
217 Self::Bool(b) => Some(*b),
218 _ => None,
219 }
220 }
221
222 #[must_use]
224 pub const fn as_int(&self) -> Option<i64> {
225 match self {
226 Self::Int(i) => Some(*i),
227 _ => None,
228 }
229 }
230
231 #[must_use]
233 pub const fn as_float(&self) -> Option<f64> {
234 match self {
235 Self::Float(f) => Some(*f),
236 _ => None,
237 }
238 }
239
240 #[must_use]
242 pub fn as_sequence(&self) -> Option<&[Self]> {
243 match self {
244 Self::Sequence(s) => Some(s),
245 _ => None,
246 }
247 }
248
249 #[must_use]
251 pub const fn as_mapping(&self) -> Option<&Mapping> {
252 match self {
253 Self::Mapping(m) => Some(m),
254 _ => None,
255 }
256 }
257
258 #[must_use]
262 pub const fn is_empty_value(&self) -> bool {
263 match self {
264 Self::Null | Self::Bool(false) | Self::Int(0) => true,
265 Self::String(s) => s.is_empty(),
266 Self::Sequence(s) => s.is_empty(),
267 Self::Mapping(m) => m.is_empty(),
268 _ => false,
269 }
270 }
271
272 #[must_use]
276 pub fn as_display_string(&self) -> Option<String> {
277 match self {
278 Self::String(s) => Some(s.clone()),
279 Self::Bool(b) => Some(b.to_string()),
280 Self::Int(i) => Some(i.to_string()),
281 Self::Float(f) => Some(format!("{f}")),
282 _ => None,
283 }
284 }
285
286 #[must_use]
296 pub fn as_display_str(&self) -> Option<std::borrow::Cow<'_, str>> {
297 match self {
298 Self::String(s) => Some(std::borrow::Cow::Borrowed(s)),
299 Self::Bool(b) => Some(std::borrow::Cow::Owned(b.to_string())),
300 Self::Int(i) => Some(std::borrow::Cow::Owned(i.to_string())),
301 Self::Float(f) => Some(std::borrow::Cow::Owned(format!("{f}"))),
302 _ => None,
303 }
304 }
305}
306
307impl fmt::Display for Value {
308 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
309 f.write_str(&self.to_yaml_string())
310 }
311}
312
313impl From<&str> for Value {
314 fn from(s: &str) -> Self {
315 Self::String(s.to_string())
316 }
317}
318
319impl From<String> for Value {
320 fn from(s: String) -> Self {
321 Self::String(s)
322 }
323}
324
325impl From<bool> for Value {
326 fn from(b: bool) -> Self {
327 Self::Bool(b)
328 }
329}
330
331impl From<i64> for Value {
332 fn from(i: i64) -> Self {
333 Self::Int(i)
334 }
335}
336
337impl<T: Into<Self>> From<Vec<T>> for Value {
338 fn from(v: Vec<T>) -> Self {
339 Self::Sequence(v.into_iter().map(Into::into).collect())
340 }
341}
342
343impl From<Mapping> for Value {
344 fn from(m: Mapping) -> Self {
345 Self::Mapping(m)
346 }
347}
348
349impl std::str::FromStr for Value {
350 type Err = YamlError;
351 fn from_str(s: &str) -> Result<Self, Self::Err> {
352 Self::parse(s)
353 }
354}
355
356impl From<i32> for Value {
357 fn from(i: i32) -> Self {
358 Self::Int(i64::from(i))
359 }
360}
361
362impl From<i16> for Value {
363 fn from(i: i16) -> Self {
364 Self::Int(i64::from(i))
365 }
366}
367
368impl From<i8> for Value {
369 fn from(i: i8) -> Self {
370 Self::Int(i64::from(i))
371 }
372}
373
374impl From<u32> for Value {
375 fn from(u: u32) -> Self {
376 Self::Int(i64::from(u))
377 }
378}
379
380impl From<u16> for Value {
381 fn from(u: u16) -> Self {
382 Self::Int(i64::from(u))
383 }
384}
385
386impl From<u8> for Value {
387 fn from(u: u8) -> Self {
388 Self::Int(i64::from(u))
389 }
390}
391
392impl From<u64> for Value {
393 fn from(u: u64) -> Self {
394 Self::Int(i64::try_from(u).unwrap_or(i64::MAX))
395 }
396}
397
398impl From<usize> for Value {
399 fn from(u: usize) -> Self {
400 Self::Int(i64::try_from(u).unwrap_or(i64::MAX))
401 }
402}
403
404impl From<f64> for Value {
405 fn from(f: f64) -> Self {
406 Self::Float(f)
407 }
408}
409
410impl From<f32> for Value {
411 fn from(f: f32) -> Self {
412 Self::Float(f64::from(f))
413 }
414}
415
416impl From<&String> for Value {
417 fn from(s: &String) -> Self {
418 Self::String(s.clone())
419 }
420}
421
422impl From<std::borrow::Cow<'_, str>> for Value {
423 fn from(s: std::borrow::Cow<'_, str>) -> Self {
424 Self::String(s.into_owned())
425 }
426}
427
428impl From<()> for Value {
429 fn from((): ()) -> Self {
430 Self::Null
431 }
432}
433
434impl<T: Into<Self>> From<Option<T>> for Value {
435 fn from(opt: Option<T>) -> Self {
436 opt.map_or(Self::Null, Into::into)
437 }
438}
439
440impl fmt::Display for Mapping {
441 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
442 f.write_str(&Value::Mapping(self.clone()).to_yaml_string())
443 }
444}
445
446impl IntoIterator for Mapping {
447 type Item = (Value, Value);
448 type IntoIter = std::vec::IntoIter<(Value, Value)>;
449 fn into_iter(self) -> Self::IntoIter {
450 self.entries.into_iter()
451 }
452}
453
454impl<'a> IntoIterator for &'a Mapping {
455 type Item = (&'a Value, &'a Value);
456 type IntoIter = std::iter::Map<
457 std::slice::Iter<'a, (Value, Value)>,
458 fn(&(Value, Value)) -> (&Value, &Value),
459 >;
460 fn into_iter(self) -> Self::IntoIter {
461 const fn map_ref(entry: &(Value, Value)) -> (&Value, &Value) {
462 (&entry.0, &entry.1)
463 }
464 self.entries.iter().map(map_ref)
465 }
466}
467
468impl<'a> IntoIterator for &'a mut Mapping {
469 type Item = (&'a mut Value, &'a mut Value);
470 type IntoIter = std::iter::Map<
471 std::slice::IterMut<'a, (Value, Value)>,
472 fn(&mut (Value, Value)) -> (&mut Value, &mut Value),
473 >;
474 fn into_iter(self) -> Self::IntoIter {
475 const fn map_mut(entry: &mut (Value, Value)) -> (&mut Value, &mut Value) {
476 (&mut entry.0, &mut entry.1)
477 }
478 self.entries.iter_mut().map(map_mut)
479 }
480}
481
482impl FromIterator<(Value, Value)> for Mapping {
483 fn from_iter<T: IntoIterator<Item = (Value, Value)>>(iter: T) -> Self {
484 Self {
485 entries: iter.into_iter().collect(),
486 }
487 }
488}
489
490impl FromIterator<(String, Value)> for Mapping {
491 fn from_iter<T: IntoIterator<Item = (String, Value)>>(iter: T) -> Self {
492 let mut map = Self::new();
493 for (k, v) in iter {
494 map.insert(k, v);
495 }
496 map
497 }
498}
499
500impl<'a> FromIterator<(&'a str, Value)> for Mapping {
501 fn from_iter<T: IntoIterator<Item = (&'a str, Value)>>(iter: T) -> Self {
502 let mut map = Self::new();
503 for (k, v) in iter {
504 map.insert(k, v);
505 }
506 map
507 }
508}
509
510impl Extend<(Value, Value)> for Mapping {
511 fn extend<T: IntoIterator<Item = (Value, Value)>>(&mut self, iter: T) {
512 self.entries.extend(iter);
513 }
514}
515
516impl Extend<(String, Value)> for Mapping {
517 fn extend<T: IntoIterator<Item = (String, Value)>>(&mut self, iter: T) {
518 for (k, v) in iter {
519 self.insert(k, v);
520 }
521 }
522}
523
524impl<'a> Extend<(&'a str, Value)> for Mapping {
525 fn extend<T: IntoIterator<Item = (&'a str, Value)>>(&mut self, iter: T) {
526 for (k, v) in iter {
527 self.insert(k, v);
528 }
529 }
530}