1use crate::scanner::QuoteStyle;
4use indexmap::IndexMap;
5use std::fmt;
6use std::hash::{Hash, Hasher};
7
8#[derive(Debug, Clone, PartialEq, Eq)]
10pub struct Comments {
11 pub leading: Vec<String>,
13 pub trailing: Option<String>,
15 pub inner: Vec<String>,
17}
18
19impl Comments {
20 pub const fn new() -> Self {
22 Self {
23 leading: Vec::new(),
24 trailing: None,
25 inner: Vec::new(),
26 }
27 }
28
29 pub const fn is_empty(&self) -> bool {
31 self.leading.is_empty() && self.trailing.is_none() && self.inner.is_empty()
32 }
33
34 pub fn add_leading<S: Into<String>>(&mut self, comment: S) {
36 self.leading.push(comment.into());
37 }
38
39 pub fn set_trailing<S: Into<String>>(&mut self, comment: S) {
41 self.trailing = Some(comment.into());
42 }
43
44 pub fn add_inner<S: Into<String>>(&mut self, comment: S) {
46 self.inner.push(comment.into());
47 }
48}
49
50impl Default for Comments {
51 fn default() -> Self {
52 Self::new()
53 }
54}
55
56#[derive(Debug, Clone, PartialEq, Eq)]
58pub enum IndentStyle {
59 Spaces(usize),
61 Tabs,
63}
64
65impl Default for IndentStyle {
66 fn default() -> Self {
67 Self::Spaces(2)
68 }
69}
70
71#[derive(Debug, Clone, PartialEq, Eq)]
73pub struct Style {
74 pub quote_style: Option<QuoteStyle>,
76 pub indent_style: Option<IndentStyle>,
78}
79
80impl Style {
81 pub const fn new() -> Self {
83 Self {
84 quote_style: None,
85 indent_style: None,
86 }
87 }
88
89 pub const fn with_quote_style(quote_style: QuoteStyle) -> Self {
91 Self {
92 quote_style: Some(quote_style),
93 indent_style: None,
94 }
95 }
96
97 pub const fn with_indent_style(indent_style: IndentStyle) -> Self {
99 Self {
100 quote_style: None,
101 indent_style: Some(indent_style),
102 }
103 }
104
105 pub const fn with_styles(quote_style: QuoteStyle, indent_style: IndentStyle) -> Self {
107 Self {
108 quote_style: Some(quote_style),
109 indent_style: Some(indent_style),
110 }
111 }
112
113 pub const fn is_empty(&self) -> bool {
115 self.quote_style.is_none() && self.indent_style.is_none()
116 }
117}
118
119impl Default for Style {
120 fn default() -> Self {
121 Self::new()
122 }
123}
124
125#[derive(Debug, Clone, PartialEq, Eq)]
127pub struct CommentedValue {
128 pub value: Value,
130 pub comments: Comments,
132 pub style: Style,
134}
135
136impl CommentedValue {
137 pub const fn new(value: Value) -> Self {
139 Self {
140 value,
141 comments: Comments::new(),
142 style: Style::new(),
143 }
144 }
145
146 pub fn with_leading_comments(value: Value, comments: Vec<String>) -> Self {
148 let mut commented = Self::new(value);
149 commented.comments.leading = comments;
150 commented
151 }
152
153 pub fn with_trailing_comment(value: Value, comment: String) -> Self {
155 let mut commented = Self::new(value);
156 commented.comments.trailing = Some(comment);
157 commented
158 }
159
160 pub fn add_leading_comment<S: Into<String>>(&mut self, comment: S) {
162 self.comments.add_leading(comment);
163 }
164
165 pub fn set_trailing_comment<S: Into<String>>(&mut self, comment: S) {
167 self.comments.set_trailing(comment);
168 }
169
170 pub const fn has_comments(&self) -> bool {
172 !self.comments.is_empty()
173 }
174
175 pub const fn with_quote_style(value: Value, quote_style: QuoteStyle) -> Self {
177 Self {
178 value,
179 comments: Comments::new(),
180 style: Style::with_quote_style(quote_style),
181 }
182 }
183
184 pub const fn set_quote_style(&mut self, quote_style: QuoteStyle) {
186 self.style.quote_style = Some(quote_style);
187 }
188
189 pub const fn quote_style(&self) -> Option<&QuoteStyle> {
191 self.style.quote_style.as_ref()
192 }
193
194 pub const fn has_style(&self) -> bool {
196 !self.style.is_empty()
197 }
198
199 pub const fn set_indent_style(&mut self, indent_style: IndentStyle) {
201 self.style.indent_style = Some(indent_style);
202 }
203
204 pub const fn indent_style(&self) -> Option<&IndentStyle> {
206 self.style.indent_style.as_ref()
207 }
208
209 pub const fn with_indent_style(value: Value, indent_style: IndentStyle) -> Self {
211 Self {
212 value,
213 comments: Comments::new(),
214 style: Style::with_indent_style(indent_style),
215 }
216 }
217}
218
219impl From<Value> for CommentedValue {
220 fn from(value: Value) -> Self {
221 Self::new(value)
222 }
223}
224
225#[derive(Debug, Clone)]
227pub enum Value {
228 Null,
230 Bool(bool),
232 Int(i64),
234 Float(f64),
236 String(String),
238 Sequence(Vec<Value>),
240 Mapping(IndexMap<Value, Value>),
242}
243
244impl Value {
245 pub const fn null() -> Self {
247 Self::Null
248 }
249
250 pub const fn bool(b: bool) -> Self {
252 Self::Bool(b)
253 }
254
255 pub const fn int(i: i64) -> Self {
257 Self::Int(i)
258 }
259
260 pub const fn float(f: f64) -> Self {
262 Self::Float(f)
263 }
264
265 pub fn string(s: impl Into<String>) -> Self {
267 Self::String(s.into())
268 }
269
270 pub const fn sequence() -> Self {
272 Self::Sequence(Vec::new())
273 }
274
275 pub const fn sequence_with(values: Vec<Self>) -> Self {
277 Self::Sequence(values)
278 }
279
280 pub fn mapping() -> Self {
282 Self::Mapping(IndexMap::new())
283 }
284
285 pub fn mapping_with(pairs: Vec<(Self, Self)>) -> Self {
287 let mut map = IndexMap::new();
288 for (key, value) in pairs {
289 map.insert(key, value);
290 }
291 Self::Mapping(map)
292 }
293
294 pub const fn type_name(&self) -> &'static str {
296 match self {
297 Self::Null => "null",
298 Self::Bool(_) => "bool",
299 Self::Int(_) => "int",
300 Self::Float(_) => "float",
301 Self::String(_) => "string",
302 Self::Sequence(_) => "sequence",
303 Self::Mapping(_) => "mapping",
304 }
305 }
306
307 pub const fn is_null(&self) -> bool {
309 matches!(self, Self::Null)
310 }
311
312 pub const fn is_bool(&self) -> bool {
314 matches!(self, Self::Bool(_))
315 }
316
317 pub const fn is_int(&self) -> bool {
319 matches!(self, Self::Int(_))
320 }
321
322 pub const fn is_float(&self) -> bool {
324 matches!(self, Self::Float(_))
325 }
326
327 pub const fn is_string(&self) -> bool {
329 matches!(self, Self::String(_))
330 }
331
332 pub const fn is_sequence(&self) -> bool {
334 matches!(self, Self::Sequence(_))
335 }
336
337 pub const fn is_mapping(&self) -> bool {
339 matches!(self, Self::Mapping(_))
340 }
341
342 pub const fn is_number(&self) -> bool {
344 matches!(self, Self::Int(_) | Self::Float(_))
345 }
346
347 pub fn len(&self) -> Option<usize> {
349 match self {
350 Self::Sequence(seq) => Some(seq.len()),
351 Self::Mapping(map) => Some(map.len()),
352 _ => None,
353 }
354 }
355
356 pub fn is_empty(&self) -> bool {
358 match self {
359 Self::Sequence(seq) => seq.is_empty(),
360 Self::Mapping(map) => map.is_empty(),
361 Self::String(s) => s.is_empty(),
362 _ => false,
363 }
364 }
365
366 pub const fn as_bool(&self) -> Option<bool> {
368 match self {
369 Self::Bool(b) => Some(*b),
370 _ => None,
371 }
372 }
373
374 pub const fn as_int(&self) -> Option<i64> {
376 match self {
377 Self::Int(i) => Some(*i),
378 _ => None,
379 }
380 }
381
382 pub const fn as_float(&self) -> Option<f64> {
384 match self {
385 Self::Float(f) => Some(*f),
386 Self::Int(i) => Some(*i as f64),
387 _ => None,
388 }
389 }
390
391 pub fn as_str(&self) -> Option<&str> {
393 match self {
394 Self::String(s) => Some(s),
395 _ => None,
396 }
397 }
398
399 pub const fn as_sequence(&self) -> Option<&Vec<Self>> {
401 match self {
402 Self::Sequence(seq) => Some(seq),
403 _ => None,
404 }
405 }
406
407 pub const fn as_sequence_mut(&mut self) -> Option<&mut Vec<Self>> {
409 match self {
410 Self::Sequence(seq) => Some(seq),
411 _ => None,
412 }
413 }
414
415 pub const fn as_mapping(&self) -> Option<&IndexMap<Self, Self>> {
417 match self {
418 Self::Mapping(map) => Some(map),
419 _ => None,
420 }
421 }
422
423 pub const fn as_mapping_mut(&mut self) -> Option<&mut IndexMap<Self, Self>> {
425 match self {
426 Self::Mapping(map) => Some(map),
427 _ => None,
428 }
429 }
430
431 pub fn get(&self, index: &Self) -> Option<&Self> {
433 match (self, index) {
434 (Self::Sequence(seq), Self::Int(i)) => {
435 if *i >= 0 && (*i as usize) < seq.len() {
436 seq.get(*i as usize)
437 } else {
438 None
439 }
440 }
441 (Self::Mapping(map), key) => map.get(key),
442 _ => None,
443 }
444 }
445
446 pub fn get_str(&self, key: &str) -> Option<&Self> {
448 match self {
449 Self::Mapping(map) => map.get(&Self::String(key.to_string())),
450 _ => None,
451 }
452 }
453
454 pub fn get_index(&self, index: usize) -> Option<&Self> {
456 match self {
457 Self::Sequence(seq) => seq.get(index),
458 _ => None,
459 }
460 }
461
462 pub fn get_mut(&mut self, index: &Self) -> Option<&mut Self> {
464 match (self, index) {
465 (Self::Sequence(seq), Self::Int(i)) => {
466 if *i >= 0 && (*i as usize) < seq.len() {
467 seq.get_mut(*i as usize)
468 } else {
469 None
470 }
471 }
472 (Self::Mapping(map), key) => map.get_mut(key),
473 _ => None,
474 }
475 }
476}
477
478impl PartialEq for Value {
480 fn eq(&self, other: &Self) -> bool {
481 match (self, other) {
482 (Value::Null, Value::Null) => true,
483 (Value::Bool(a), Value::Bool(b)) => a == b,
484 (Value::Int(a), Value::Int(b)) => a == b,
485 (Value::Float(a), Value::Float(b)) => {
486 if a.is_nan() && b.is_nan() {
488 true
489 } else {
490 a == b
491 }
492 }
493 (Value::String(a), Value::String(b)) => a == b,
494 (Value::Sequence(a), Value::Sequence(b)) => a == b,
495 (Value::Mapping(a), Value::Mapping(b)) => a == b,
496 _ => false,
497 }
498 }
499}
500
501impl Eq for Value {}
503
504impl Hash for Value {
505 fn hash<H: Hasher>(&self, state: &mut H) {
506 match self {
507 Self::Null => 0u8.hash(state),
508 Self::Bool(b) => {
509 1u8.hash(state);
510 b.hash(state);
511 }
512 Self::Int(i) => {
513 2u8.hash(state);
514 i.hash(state);
515 }
516 Self::Float(f) => {
517 3u8.hash(state);
518 if f.is_nan() {
520 u64::MAX.hash(state);
521 } else if *f == 0.0 {
522 0u64.hash(state);
523 } else {
524 f.to_bits().hash(state);
525 }
526 }
527 Self::String(s) => {
528 4u8.hash(state);
529 s.hash(state);
530 }
531 Self::Sequence(seq) => {
532 5u8.hash(state);
533 seq.hash(state);
534 }
535 Self::Mapping(map) => {
536 6u8.hash(state);
537 for (k, v) in map.iter() {
539 k.hash(state);
540 v.hash(state);
541 }
542 }
543 }
544 }
545}
546
547impl fmt::Display for Value {
548 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
549 match self {
550 Self::Null => write!(f, "null"),
551 Self::Bool(b) => write!(f, "{}", b),
552 Self::Int(i) => write!(f, "{}", i),
553 Self::Float(fl) => write!(f, "{}", fl),
554 Self::String(s) => write!(f, "\"{}\"", s),
555 Self::Sequence(seq) => {
556 write!(f, "[")?;
557 for (i, item) in seq.iter().enumerate() {
558 if i > 0 {
559 write!(f, ", ")?;
560 }
561 write!(f, "{}", item)?;
562 }
563 write!(f, "]")
564 }
565 Self::Mapping(map) => {
566 write!(f, "{{")?;
567 for (i, (key, value)) in map.iter().enumerate() {
568 if i > 0 {
569 write!(f, ", ")?;
570 }
571 write!(f, "{}: {}", key, value)?;
572 }
573 write!(f, "}}")
574 }
575 }
576 }
577}
578
579impl From<()> for Value {
581 fn from(_: ()) -> Self {
582 Self::Null
583 }
584}
585
586impl From<bool> for Value {
587 fn from(b: bool) -> Self {
588 Self::Bool(b)
589 }
590}
591
592impl From<i64> for Value {
593 fn from(i: i64) -> Self {
594 Self::Int(i)
595 }
596}
597
598impl From<i32> for Value {
599 fn from(i: i32) -> Self {
600 Self::Int(i64::from(i))
601 }
602}
603
604impl From<f64> for Value {
605 fn from(f: f64) -> Self {
606 Self::Float(f)
607 }
608}
609
610impl From<f32> for Value {
611 fn from(f: f32) -> Self {
612 Self::Float(f64::from(f))
613 }
614}
615
616impl From<String> for Value {
617 fn from(s: String) -> Self {
618 Self::String(s)
619 }
620}
621
622impl From<&str> for Value {
623 fn from(s: &str) -> Self {
624 Self::String(s.to_string())
625 }
626}
627
628impl From<Vec<Self>> for Value {
629 fn from(seq: Vec<Self>) -> Self {
630 Self::Sequence(seq)
631 }
632}
633
634impl From<IndexMap<Self, Self>> for Value {
635 fn from(map: IndexMap<Self, Self>) -> Self {
636 Self::Mapping(map)
637 }
638}
639
640#[cfg(feature = "serde")]
641impl serde::Serialize for Value {
642 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
643 where
644 S: serde::Serializer,
645 {
646 match self {
647 Self::Null => serializer.serialize_none(),
648 Self::Bool(b) => serializer.serialize_bool(*b),
649 Self::Int(i) => serializer.serialize_i64(*i),
650 Self::Float(f) => serializer.serialize_f64(*f),
651 Self::String(s) => serializer.serialize_str(s),
652 Self::Sequence(seq) => seq.serialize(serializer),
653 Self::Mapping(map) => map.serialize(serializer),
654 }
655 }
656}
657
658#[cfg(test)]
659mod tests {
660 use super::*;
661
662 #[test]
663 fn test_value_creation() {
664 assert_eq!(Value::null(), Value::Null);
665 assert_eq!(Value::bool(true), Value::Bool(true));
666 assert_eq!(Value::int(42), Value::Int(42));
667 assert_eq!(Value::float(3.14), Value::Float(3.14));
668 assert_eq!(Value::string("hello"), Value::String("hello".to_string()));
669 }
670
671 #[test]
672 fn test_value_type_checks() {
673 let null_val = Value::null();
674 let bool_val = Value::bool(true);
675 let int_val = Value::int(42);
676 let string_val = Value::string("test");
677
678 assert!(null_val.is_null());
679 assert!(bool_val.is_bool());
680 assert!(int_val.is_int());
681 assert!(string_val.is_string());
682
683 assert!(!null_val.is_bool());
684 assert!(!bool_val.is_int());
685 }
686
687 #[test]
688 fn test_value_conversions() {
689 let bool_val = Value::bool(true);
690 let int_val = Value::int(42);
691 let float_val = Value::float(3.14);
692 let string_val = Value::string("hello");
693
694 assert_eq!(bool_val.as_bool(), Some(true));
695 assert_eq!(int_val.as_int(), Some(42));
696 assert_eq!(float_val.as_float(), Some(3.14));
697 assert_eq!(string_val.as_str(), Some("hello"));
698
699 assert_eq!(bool_val.as_int(), None);
700 assert_eq!(int_val.as_bool(), None);
701 }
702
703 #[test]
704 fn test_sequence_operations() {
705 let mut seq = Value::sequence();
706 if let Value::Sequence(ref mut v) = seq {
707 v.push(Value::int(1));
708 v.push(Value::string("hello"));
709 }
710
711 assert!(seq.is_sequence());
712 assert_eq!(seq.as_sequence().unwrap().len(), 2);
713
714 let index = Value::int(0);
715 assert_eq!(seq.get(&index), Some(&Value::int(1)));
716 }
717
718 #[test]
719 fn test_mapping_operations() {
720 let mut map = Value::mapping();
721 if let Value::Mapping(ref mut m) = map {
722 m.insert(Value::string("key"), Value::int(42));
723 m.insert(Value::string("name"), Value::string("test"));
724 }
725
726 assert!(map.is_mapping());
727 assert_eq!(map.as_mapping().unwrap().len(), 2);
728
729 let key = Value::string("key");
730 assert_eq!(map.get(&key), Some(&Value::int(42)));
731 }
732
733 #[test]
734 fn test_value_display() {
735 assert_eq!(format!("{}", Value::null()), "null");
736 assert_eq!(format!("{}", Value::bool(true)), "true");
737 assert_eq!(format!("{}", Value::int(42)), "42");
738 assert_eq!(format!("{}", Value::string("hello")), "\"hello\"");
739 }
740
741 #[test]
742 fn test_value_equality() {
743 assert_eq!(Value::int(42), Value::int(42));
744 assert_eq!(Value::float(3.14), Value::float(3.14));
745 assert_ne!(Value::int(42), Value::float(42.0));
746
747 let nan1 = Value::float(f64::NAN);
749 let nan2 = Value::float(f64::NAN);
750 assert_eq!(nan1, nan2); }
752
753 #[test]
754 fn test_conversions_from_primitives() {
755 assert_eq!(Value::from(true), Value::Bool(true));
756 assert_eq!(Value::from(42i32), Value::Int(42));
757 assert_eq!(Value::from(42i64), Value::Int(42));
758 assert_eq!(Value::from(3.14f64), Value::Float(3.14));
759 assert_eq!(Value::from("hello"), Value::String("hello".to_string()));
760 assert_eq!(
761 Value::from("hello".to_string()),
762 Value::String("hello".to_string())
763 );
764 }
765}