1#![allow(redundant_semicolons)]
12
13use std::cmp::{Ord, Ordering, PartialOrd};
14use std::collections::{BTreeMap, BTreeSet, LinkedList};
15use std::f64;
16use std::fmt::{Display, Formatter};
17
18use chrono::{
19 DateTime,
20 SecondsFormat,
21 TimeZone, Utc,
23};
24use num::BigInt;
25use ordered_float::OrderedFloat;
26use uuid::Uuid;
27
28use crate::symbols;
29
30use bytes::Bytes;
31use hex::encode;
32#[derive(PartialEq, Eq, Hash, Clone, Debug)]
34pub enum Value {
35 Nil,
36 Boolean(bool),
37 Integer(i64),
38 Instant(DateTime<Utc>),
39 BigInteger(BigInt),
40 Float(OrderedFloat<f64>),
41 Text(String),
42 Uuid(Uuid),
43 PlainSymbol(symbols::PlainSymbol),
44 NamespacedSymbol(symbols::NamespacedSymbol),
45 Keyword(symbols::Keyword),
46 Vector(Vec<Value>),
47 List(LinkedList<Value>),
51 Set(BTreeSet<Value>),
56 Map(BTreeMap<Value, Value>),
57 Bytes(Bytes),
58}
59
60#[derive(PartialEq, Eq, Hash, Clone, Debug)]
63pub enum SpannedValue {
64 Nil,
65 Boolean(bool),
66 Integer(i64),
67 Instant(DateTime<Utc>),
68 BigInteger(BigInt),
69 Float(OrderedFloat<f64>),
70 Text(String),
71 Uuid(Uuid),
72 PlainSymbol(symbols::PlainSymbol),
73 NamespacedSymbol(symbols::NamespacedSymbol),
74 Keyword(symbols::Keyword),
75 Vector(Vec<ValueAndSpan>),
76 List(LinkedList<ValueAndSpan>),
77 Set(BTreeSet<ValueAndSpan>),
78 Map(BTreeMap<ValueAndSpan, ValueAndSpan>),
79 Bytes(Bytes),
80}
81
82#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
84pub struct Span(pub u32, pub u32);
85
86impl Span {
87 pub fn new(start: usize, end: usize) -> Span {
88 Span(start as u32, end as u32)
89 }
90}
91
92#[derive(PartialEq, Eq, Hash, Clone, Debug)]
95pub struct ValueAndSpan {
96 pub inner: SpannedValue,
97 pub span: Span,
98}
99
100impl ValueAndSpan {
101 pub fn new<I>(spanned_value: SpannedValue, span: I) -> ValueAndSpan
102 where
103 I: Into<Option<Span>>,
104 {
105 ValueAndSpan {
106 inner: spanned_value,
107 span: span.into().unwrap_or(Span(0, 0)), }
109 }
110
111 pub fn into_atom(self) -> Option<ValueAndSpan> {
112 if self.inner.is_atom() {
113 Some(self)
114 } else {
115 None
116 }
117 }
118
119 pub fn is_atom(&self) -> bool {
120 self.inner.is_atom()
121 }
122
123 pub fn as_atom(&self) -> Option<&ValueAndSpan> {
124 if self.inner.is_atom() {
125 Some(self)
126 } else {
127 None
128 }
129 }
130
131 pub fn into_text(self) -> Option<String> {
132 self.inner.into_text()
133 }
134
135 pub fn as_text(&self) -> Option<&String> {
136 self.inner.as_text()
137 }
138}
139
140impl Value {
141 pub fn with_spans(self) -> ValueAndSpan {
145 let s = self.to_pretty(120).unwrap();
146 use crate::parse;
147 let with_spans = parse::value(&s).unwrap();
148 assert_eq!(self, with_spans.clone().without_spans());
149 with_spans
150 }
151}
152
153impl From<SpannedValue> for Value {
154 fn from(src: SpannedValue) -> Value {
155 match src {
156 SpannedValue::Nil => Value::Nil,
157 SpannedValue::Boolean(v) => Value::Boolean(v),
158 SpannedValue::Integer(v) => Value::Integer(v),
159 SpannedValue::Instant(v) => Value::Instant(v),
160 SpannedValue::BigInteger(v) => Value::BigInteger(v),
161 SpannedValue::Float(v) => Value::Float(v),
162 SpannedValue::Text(v) => Value::Text(v),
163 SpannedValue::Uuid(v) => Value::Uuid(v),
164 SpannedValue::PlainSymbol(v) => Value::PlainSymbol(v),
165 SpannedValue::NamespacedSymbol(v) => Value::NamespacedSymbol(v),
166 SpannedValue::Keyword(v) => Value::Keyword(v),
167 SpannedValue::Vector(v) => {
168 Value::Vector(v.into_iter().map(|x| x.without_spans()).collect())
169 }
170 SpannedValue::List(v) => {
171 Value::List(v.into_iter().map(|x| x.without_spans()).collect())
172 }
173 SpannedValue::Set(v) => Value::Set(v.into_iter().map(|x| x.without_spans()).collect()),
174 SpannedValue::Map(v) => Value::Map(
175 v.into_iter()
176 .map(|(x, y)| (x.without_spans(), y.without_spans()))
177 .collect(),
178 ),
179 SpannedValue::Bytes(b) => Value::Bytes(b),
180 }
181 }
182}
183
184impl From<ValueAndSpan> for Value {
185 fn from(src: ValueAndSpan) -> Value {
186 src.inner.into()
187 }
188}
189
190macro_rules! def_from {
193 ($name: ident, $out: ty, $kind: path, $t: ty, $( $transform: expr ),* ) => {
194 pub fn $name(src: $t) -> $out {
195 $( let src = $transform(src); )*
196 $kind(src)
197 }
198 }
199}
200
201macro_rules! def_from_option {
204 ($name: ident, $out: ty, $kind: path, $t: ty, $( $transform: expr ),* ) => {
205 pub fn $name(src: $t) -> Option<$out> {
206 $( let src = $transform(src); )*
207 src.map($kind)
208 }
209 }
210}
211
212macro_rules! def_is {
215 ($name: ident, $pat: pat) => {
216 pub fn $name(&self) -> bool {
217 matches!(*self, $pat)
218 }
219 };
220}
221
222macro_rules! def_as {
226 ($name: ident, $kind: path, $t: ty, $( $transform: expr ),* ) => {
227 pub fn $name(&self) -> Option<$t> {
228 match *self { $kind(v) => { $( let v = $transform(v) )*; Some(v) }, _ => None }
229 }
230 }
231}
232
233macro_rules! def_as_ref {
237 ($name: ident, $kind: path, $t: ty) => {
238 pub fn $name(&self) -> Option<&$t> {
239 match *self {
240 $kind(ref v) => Some(v),
241 _ => None,
242 }
243 }
244 };
245}
246
247macro_rules! def_into {
251 ($name: ident, $kind: path, $t: ty, $( $transform: expr ),* ) => {
252 pub fn $name(self) -> Option<$t> {
253 match self { $kind(v) => { $( let v = $transform(v) )*; Some(v) }, _ => None }
254 }
255 }
256}
257
258macro_rules! to_symbol {
273 ( $namespace:expr, $name:expr, $t:tt ) => {
274 $namespace.into().map_or_else(
275 || $t::PlainSymbol(symbols::PlainSymbol::plain($name)),
276 |ns| $t::NamespacedSymbol(symbols::NamespacedSymbol::namespaced(ns, $name)),
277 )
278 };
279}
280
281macro_rules! to_keyword {
296 ( $namespace:expr, $name:expr, $t:tt ) => {
297 $namespace.into().map_or_else(
298 || $t::Keyword(symbols::Keyword::plain($name)),
299 |ns| $t::Keyword(symbols::Keyword::namespaced(ns, $name)),
300 )
301 };
302}
303
304macro_rules! def_common_value_methods {
307 ( $t:tt<$tchild:tt> ) => {
308 def_is!(is_nil, $t::Nil);
309 def_is!(is_boolean, $t::Boolean(_));
310 def_is!(is_integer, $t::Integer(_));
311 def_is!(is_instant, $t::Instant(_));
312 def_is!(is_big_integer, $t::BigInteger(_));
313 def_is!(is_float, $t::Float(_));
314 def_is!(is_text, $t::Text(_));
315 def_is!(is_uuid, $t::Uuid(_));
316 def_is!(is_symbol, $t::PlainSymbol(_));
317 def_is!(is_namespaced_symbol, $t::NamespacedSymbol(_));
318 def_is!(is_vector, $t::Vector(_));
319 def_is!(is_list, $t::List(_));
320 def_is!(is_set, $t::Set(_));
321 def_is!(is_map, $t::Map(_));
322 def_is!(is_bytes, $t::Bytes(_));
323
324 pub fn is_keyword(&self) -> bool {
325 match self {
326 $t::Keyword(ref k) => !k.is_namespaced(),
327 _ => false,
328 }
329 }
330
331 pub fn is_namespaced_keyword(&self) -> bool {
332 match self {
333 $t::Keyword(ref k) => k.is_namespaced(),
334 _ => false,
335 }
336 }
337
338 pub fn as_nil(&self) -> Option<()> {
341 match *self { $t::Nil => Some(()), _ => None }
342 }
343
344 def_as!(as_boolean, $t::Boolean, bool,);
345 def_as!(as_integer, $t::Integer, i64,);
346 def_as!(as_instant, $t::Instant, DateTime<Utc>,);
347 def_as!(as_float, $t::Float, f64, |v: OrderedFloat<f64>| v.into_inner());
348
349 def_as_ref!(as_big_integer, $t::BigInteger, BigInt);
350 def_as_ref!(as_ordered_float, $t::Float, OrderedFloat<f64>);
351 def_as_ref!(as_text, $t::Text, String);
352 def_as_ref!(as_uuid, $t::Uuid, Uuid);
353 def_as_ref!(as_symbol, $t::PlainSymbol, symbols::PlainSymbol);
354 def_as_ref!(as_namespaced_symbol, $t::NamespacedSymbol, symbols::NamespacedSymbol);
355 def_as_ref!(as_bytes, $t::Bytes, Bytes);
356
357 pub fn as_keyword(&self) -> Option<&symbols::Keyword> {
358 match self {
359 $t::Keyword(ref k) => Some(k),
360 _ => None,
361 }
362 }
363
364 pub fn as_plain_keyword(&self) -> Option<&symbols::Keyword> {
365 match self {
366 $t::Keyword(ref k) if !k.is_namespaced() => Some(k),
367 _ => None,
368 }
369 }
370
371 pub fn as_namespaced_keyword(&self) -> Option<&symbols::Keyword> {
372 match self {
373 $t::Keyword(ref k) if k.is_namespaced() => Some(k),
374 _ => None,
375 }
376 }
377
378 def_as_ref!(as_vector, $t::Vector, Vec<$tchild>);
379 def_as_ref!(as_list, $t::List, LinkedList<$tchild>);
380 def_as_ref!(as_set, $t::Set, BTreeSet<$tchild>);
381 def_as_ref!(as_map, $t::Map, BTreeMap<$tchild, $tchild>);
382
383 def_into!(into_boolean, $t::Boolean, bool,);
384 def_into!(into_integer, $t::Integer, i64,);
385 def_into!(into_instant, $t::Instant, DateTime<Utc>,);
386 def_into!(into_big_integer, $t::BigInteger, BigInt,);
387 def_into!(into_ordered_float, $t::Float, OrderedFloat<f64>,);
388 def_into!(into_float, $t::Float, f64, |v: OrderedFloat<f64>| v.into_inner());
389 def_into!(into_text, $t::Text, String,);
390 def_into!(into_uuid, $t::Uuid, Uuid,);
391 def_into!(into_symbol, $t::PlainSymbol, symbols::PlainSymbol,);
392 def_into!(into_namespaced_symbol, $t::NamespacedSymbol, symbols::NamespacedSymbol,);
393 def_into!(into_bytes, $t::Bytes, Bytes,);
394
395 pub fn into_keyword(self) -> Option<symbols::Keyword> {
396 match self {
397 $t::Keyword(k) => Some(k),
398 _ => None,
399 }
400 }
401
402 pub fn into_plain_keyword(self) -> Option<symbols::Keyword> {
403 match self {
404 $t::Keyword(k) => {
405 if !k.is_namespaced() {
406 Some(k)
407 } else {
408 None
409 }
410 },
411 _ => None,
412 }
413 }
414
415 pub fn into_namespaced_keyword(self) -> Option<symbols::Keyword> {
416 match self {
417 $t::Keyword(k) => {
418 if k.is_namespaced() {
419 Some(k)
420 } else {
421 None
422 }
423 },
424 _ => None,
425 }
426 }
427
428
429 def_into!(into_vector, $t::Vector, Vec<$tchild>,);
430 def_into!(into_list, $t::List, LinkedList<$tchild>,);
431 def_into!(into_set, $t::Set, BTreeSet<$tchild>,);
432 def_into!(into_map, $t::Map, BTreeMap<$tchild, $tchild>,);
433
434 def_from_option!(from_bigint, $t, $t::BigInteger, &str, |src: &str| src.parse::<BigInt>().ok());
435 def_from!(from_float, $t, $t::Float, f64, |src: f64| OrderedFloat::from(src));
436 def_from!(from_ordered_float, $t, $t::Float, OrderedFloat<f64>,);
437
438 pub fn from_symbol<'a, T: Into<Option<&'a str>>>(namespace: T, name: &str) -> $t {
439 to_symbol!(namespace, name, $t)
440 }
441
442 pub fn from_keyword<'a, T: Into<Option<&'a str>>>(namespace: T, name: &str) -> $t {
443 to_keyword!(namespace, name, $t)
444 }
445
446 fn precedence(&self) -> i32 {
447 match *self {
448 $t::Nil => 0,
449 $t::Boolean(_) => 1,
450 $t::Integer(_) => 2,
451 $t::BigInteger(_) => 3,
452 $t::Float(_) => 4,
453 $t::Instant(_) => 5,
454 $t::Text(_) => 6,
455 $t::Uuid(_) => 7,
456 $t::PlainSymbol(_) => 8,
457 $t::NamespacedSymbol(_) => 9,
458 $t::Keyword(ref k) if !k.is_namespaced() => 10,
459 $t::Keyword(_) => 11,
460 $t::Vector(_) => 12,
461 $t::List(_) => 13,
462 $t::Set(_) => 14,
463 $t::Map(_) => 15,
464 $t::Bytes(_) => 16,
465 }
466 }
467
468 pub fn is_collection(&self) -> bool {
469 match *self {
470 $t::Nil => false,
471 $t::Boolean(_) => false,
472 $t::Integer(_) => false,
473 $t::Instant(_) => false,
474 $t::BigInteger(_) => false,
475 $t::Float(_) => false,
476 $t::Text(_) => false,
477 $t::Uuid(_) => false,
478 $t::PlainSymbol(_) => false,
479 $t::NamespacedSymbol(_) => false,
480 $t::Keyword(_) => false,
481 $t::Vector(_) => true,
482 $t::List(_) => true,
483 $t::Set(_) => true,
484 $t::Map(_) => true,
485 $t::Bytes(_) => false,
486 }
487 }
488
489 pub fn is_atom(&self) -> bool {
490 !self.is_collection()
491 }
492
493 pub fn into_atom(self) -> Option<$t> {
494 if self.is_atom() {
495 Some(self)
496 } else {
497 None
498 }
499 }
500 }
501}
502
503macro_rules! def_common_value_ord {
506 ( $t:tt, $value:expr, $other:expr ) => {
507 match ($value, $other) {
508 (&$t::Nil, &$t::Nil) => Ordering::Equal,
509 (&$t::Boolean(a), &$t::Boolean(b)) => b.cmp(&a),
510 (&$t::Integer(a), &$t::Integer(b)) => b.cmp(&a),
511 (&$t::Instant(a), &$t::Instant(b)) => b.cmp(&a),
512 (&$t::BigInteger(ref a), &$t::BigInteger(ref b)) => b.cmp(a),
513 (&$t::Float(ref a), &$t::Float(ref b)) => b.cmp(a),
514 (&$t::Text(ref a), &$t::Text(ref b)) => b.cmp(a),
515 (&$t::Uuid(ref a), &$t::Uuid(ref b)) => b.cmp(a),
516 (&$t::PlainSymbol(ref a), &$t::PlainSymbol(ref b)) => b.cmp(a),
517 (&$t::NamespacedSymbol(ref a), &$t::NamespacedSymbol(ref b)) => b.cmp(a),
518 (&$t::Keyword(ref a), &$t::Keyword(ref b)) => b.cmp(a),
519 (&$t::Vector(ref a), &$t::Vector(ref b)) => b.cmp(a),
520 (&$t::List(ref a), &$t::List(ref b)) => b.cmp(a),
521 (&$t::Set(ref a), &$t::Set(ref b)) => b.cmp(a),
522 (&$t::Map(ref a), &$t::Map(ref b)) => b.cmp(a),
523 (&$t::Bytes(ref a), &$t::Bytes(ref b)) => b.cmp(a),
524 _ => $value.precedence().cmp(&$other.precedence()),
525 }
526 };
527}
528
529macro_rules! def_common_value_display {
533 ( $t:tt, $value:expr, $f:expr ) => {
534 match *$value {
535 $t::Nil => write!($f, "nil"),
536 $t::Boolean(v) => write!($f, "{}", v),
537 $t::Integer(v) => write!($f, "{}", v),
538 $t::Instant(v) => write!(
539 $f,
540 "#inst \"{}\"",
541 v.to_rfc3339_opts(SecondsFormat::AutoSi, true)
542 ),
543 $t::BigInteger(ref v) => write!($f, "{}N", v),
544 $t::Float(ref v) => {
546 if *v == OrderedFloat(f64::INFINITY) {
547 write!($f, "#f +Infinity")
548 } else if *v == OrderedFloat(f64::NEG_INFINITY) {
549 write!($f, "#f -Infinity")
550 } else if *v == OrderedFloat(f64::NAN) {
551 write!($f, "#f NaN")
552 } else {
553 write!($f, "{}", v)
554 }
555 }
556 $t::Text(ref v) => write!($f, "\"{}\"", v),
558 $t::Uuid(ref u) => write!($f, "#uuid \"{}\"", u.hyphenated().to_string()),
559 $t::PlainSymbol(ref v) => v.fmt($f),
560 $t::NamespacedSymbol(ref v) => v.fmt($f),
561 $t::Keyword(ref v) => v.fmt($f),
562 $t::Vector(ref v) => {
563 write!($f, "[")?;
564 for x in v {
565 write!($f, " {}", x)?;
566 }
567 write!($f, " ]")
568 }
569 $t::List(ref v) => {
570 write!($f, "(")?;
571 for x in v {
572 write!($f, " {}", x)?;
573 }
574 write!($f, " )")
575 }
576 $t::Set(ref v) => {
577 write!($f, "#{{")?;
578 for x in v {
579 write!($f, " {}", x)?;
580 }
581 write!($f, " }}")
582 }
583 $t::Map(ref v) => {
584 write!($f, "{{")?;
585 for (key, val) in v {
586 write!($f, " {} {}", key, val)?;
587 }
588 write!($f, " }}")
589 }
590 $t::Bytes(ref v) => {
591 let s = encode(v);
592 write!($f, "#bytes {}", s)
593 }
594 }
595 };
596}
597
598macro_rules! def_common_value_impl {
599 ( $t:tt<$tchild:tt> ) => {
600 impl $t {
601 def_common_value_methods!($t<$tchild>);
602 }
603
604 impl PartialOrd for $t {
605 fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
606 Some(self.cmp(other))
607 }
608 }
609
610 impl Ord for $t {
611 fn cmp(&self, other: &$t) -> Ordering {
612 def_common_value_ord!($t, self, other)
613 }
614 }
615
616 impl Display for $t {
617 fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result {
618 def_common_value_display!($t, self, f)
619 }
620 }
621 };
622}
623
624def_common_value_impl!(Value<Value>);
625def_common_value_impl!(SpannedValue<ValueAndSpan>);
626
627impl ValueAndSpan {
628 pub fn without_spans(self) -> Value {
629 self.inner.into()
630 }
631}
632
633impl PartialOrd for ValueAndSpan {
634 fn partial_cmp(&self, other: &ValueAndSpan) -> Option<Ordering> {
635 Some(self.cmp(other))
636 }
637}
638
639impl Ord for ValueAndSpan {
640 fn cmp(&self, other: &ValueAndSpan) -> Ordering {
641 self.inner.cmp(&other.inner)
642 }
643}
644
645impl Display for ValueAndSpan {
646 fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result {
647 self.inner.fmt(f)
648 }
649}
650
651pub trait FromMicros {
652 fn from_micros(ts: i64) -> Self;
653}
654
655impl FromMicros for DateTime<Utc> {
656 fn from_micros(ts: i64) -> Self {
657 Utc.timestamp_opt(
658 ts / 1_000_000,
659 ((ts % 1_000_000).unsigned_abs() as u32) * 1_000,
660 )
661 .unwrap()
662 }
663}
664
665pub trait ToMicros {
666 fn to_micros(&self) -> i64;
667}
668
669impl ToMicros for DateTime<Utc> {
670 fn to_micros(&self) -> i64 {
671 let major: i64 = self.timestamp() * 1_000_000;
672 let minor: i64 = self.timestamp_subsec_micros() as i64;
673 major + minor
674 }
675}
676
677pub trait FromMillis {
678 fn from_millis(ts: i64) -> Self;
679}
680
681impl FromMillis for DateTime<Utc> {
682 fn from_millis(ts: i64) -> Self {
683 Utc.timestamp_opt(ts / 1_000, ((ts % 1_000).unsigned_abs() as u32) * 1_000)
684 .unwrap()
685 }
686}
687
688pub trait ToMillis {
689 fn to_millis(&self) -> i64;
690}
691
692impl ToMillis for DateTime<Utc> {
693 fn to_millis(&self) -> i64 {
694 let major: i64 = self.timestamp() * 1_000;
695 let minor: i64 = self.timestamp_subsec_millis() as i64;
696 major + minor
697 }
698}
699
700#[cfg(test)]
701mod test {
702 extern crate chrono;
703 extern crate num;
704 extern crate ordered_float;
705
706 use super::*;
707
708 use std::cmp::Ordering;
709 use std::collections::{BTreeMap, BTreeSet, LinkedList};
710 use std::f64;
711 use std::iter::FromIterator;
712
713 use crate::parse;
714
715 use chrono::{DateTime, Utc};
716 use num::BigInt;
717 use ordered_float::OrderedFloat;
718
719 #[test]
720 fn test_micros_roundtrip() {
721 let ts_micros: i64 = 1493399581314000;
722 let dt = DateTime::<Utc>::from_micros(ts_micros);
723 assert_eq!(dt.to_micros(), ts_micros);
724 }
725
726 #[test]
727 fn test_value_from() {
728 assert_eq!(
729 Value::from_float(42f64),
730 Value::Float(OrderedFloat::from(42f64))
731 );
732 assert_eq!(
733 Value::from_ordered_float(OrderedFloat::from(42f64)),
734 Value::Float(OrderedFloat::from(42f64))
735 );
736 assert_eq!(
737 Value::from_bigint("42").unwrap(),
738 Value::BigInteger(BigInt::from(42))
739 );
740 }
741
742 #[test]
743 fn test_print_edn() {
744 assert_eq!("1234N", Value::from_bigint("1234").unwrap().to_string());
745
746 let string = "[ 1 2 ( 7.14 ) #{ 4N } { foo/bar 42 :baz/boz 43 } [ ] :five :six/seven eight nine/ten true false nil #f NaN #f -Infinity #f +Infinity ]";
747
748 let data = Value::Vector(vec![
749 Value::Integer(1),
750 Value::Integer(2),
751 Value::List(LinkedList::from_iter(vec![Value::from_float(7.14)])),
752 Value::Set(BTreeSet::from_iter(vec![Value::from_bigint("4").unwrap()])),
753 Value::Map(BTreeMap::from_iter(vec![
754 (Value::from_symbol("foo", "bar"), Value::Integer(42)),
755 (Value::from_keyword("baz", "boz"), Value::Integer(43)),
756 ])),
757 Value::Vector(vec![]),
758 Value::from_keyword(None, "five"),
759 Value::from_keyword("six", "seven"),
760 Value::from_symbol(None, "eight"),
761 Value::from_symbol("nine", "ten"),
762 Value::Boolean(true),
763 Value::Boolean(false),
764 Value::Nil,
765 Value::from_float(f64::NAN),
766 Value::from_float(f64::NEG_INFINITY),
767 Value::from_float(f64::INFINITY),
768 ]);
769
770 assert_eq!(string, data.to_string());
771 assert_eq!(string, parse::value(&data.to_string()).unwrap().to_string());
772 assert_eq!(
773 string,
774 parse::value(&data.to_string())
775 .unwrap()
776 .without_spans()
777 .to_string()
778 );
779 }
780
781 #[test]
782 fn test_ord() {
783 assert_eq!(Value::Nil.cmp(&Value::Nil), Ordering::Equal);
785 assert_eq!(
786 Value::Boolean(false).cmp(&Value::Boolean(true)),
787 Ordering::Greater
788 );
789 assert_eq!(Value::Integer(1).cmp(&Value::Integer(2)), Ordering::Greater);
790 assert_eq!(
791 Value::from_bigint("1").cmp(&Value::from_bigint("2")),
792 Ordering::Greater
793 );
794 assert_eq!(
795 Value::from_float(1f64).cmp(&Value::from_float(2f64)),
796 Ordering::Greater
797 );
798 assert_eq!(
799 Value::Text("1".to_string()).cmp(&Value::Text("2".to_string())),
800 Ordering::Greater
801 );
802 assert_eq!(
803 Value::from_symbol("a", "b").cmp(&Value::from_symbol("c", "d")),
804 Ordering::Greater
805 );
806 assert_eq!(
807 Value::from_symbol(None, "a").cmp(&Value::from_symbol(None, "b")),
808 Ordering::Greater
809 );
810 assert_eq!(
811 Value::from_keyword(":a", ":b").cmp(&Value::from_keyword(":c", ":d")),
812 Ordering::Greater
813 );
814 assert_eq!(
815 Value::from_keyword(None, ":a").cmp(&Value::from_keyword(None, ":b")),
816 Ordering::Greater
817 );
818 assert_eq!(
819 Value::Vector(vec![]).cmp(&Value::Vector(vec![])),
820 Ordering::Equal
821 );
822 assert_eq!(
823 Value::List(LinkedList::new()).cmp(&Value::List(LinkedList::new())),
824 Ordering::Equal
825 );
826 assert_eq!(
827 Value::Set(BTreeSet::new()).cmp(&Value::Set(BTreeSet::new())),
828 Ordering::Equal
829 );
830 assert_eq!(
831 Value::Map(BTreeMap::new()).cmp(&Value::Map(BTreeMap::new())),
832 Ordering::Equal
833 );
834 }
835
836 #[test]
837 fn test_keyword_as() {
838 let namespaced = symbols::Keyword::namespaced("foo", "bar");
839 let plain = symbols::Keyword::plain("bar");
840 let n_v = Value::Keyword(namespaced);
841 let p_v = Value::Keyword(plain);
842
843 assert!(n_v.as_keyword().is_some());
844 assert!(n_v.as_plain_keyword().is_none());
845 assert!(n_v.as_namespaced_keyword().is_some());
846
847 assert!(p_v.as_keyword().is_some());
848 assert!(p_v.as_plain_keyword().is_some());
849 assert!(p_v.as_namespaced_keyword().is_none());
850
851 assert!(n_v.clone().into_keyword().is_some());
852 assert!(n_v.clone().into_plain_keyword().is_none());
853 assert!(n_v.into_namespaced_keyword().is_some());
854
855 assert!(p_v.clone().into_keyword().is_some());
856 assert!(p_v.clone().into_plain_keyword().is_some());
857 assert!(p_v.into_namespaced_keyword().is_none());
858 }
859}