1use crate::array::Array;
2use crate::object::Object;
3use ordered_float::OrderedFloat;
4
5#[derive(Clone, PartialEq, Hash, Eq, Ord, PartialOrd)]
10pub enum Value {
11 Null,
12 Bool(bool),
13 String(String),
14 Array(Array),
15 Object(Object),
16 U64(u64),
17 I64(i64),
18 F64(OrderedFloat<f64>),
19}
20
21impl Default for Value {
22 fn default() -> Self {
23 Self::Null
24 }
25}
26
27impl std::fmt::Debug for Value {
28 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
29 match self {
30 Self::String(s) => fmt.write_fmt(format_args!("{:?}", s)),
31 Self::Null => fmt.write_str("nil"),
32 Self::Bool(i) => i.fmt(fmt),
33 Self::I64(i) => i.fmt(fmt),
34 Self::U64(i) => i.fmt(fmt),
35 Self::F64(i) => i.fmt(fmt),
36 Self::Array(a) => a.fmt(fmt),
37 Self::Object(o) => o.fmt(fmt),
38 }
39 }
40}
41
42impl Value {
43 pub fn variant_name(&self) -> &str {
44 match self {
45 Self::Null => "Null",
46 Self::Bool(_) => "Bool",
47 Self::String(_) => "String",
48 Self::Array(_) => "Array",
49 Self::Object(_) => "Object",
50 Self::U64(_) => "U64",
51 Self::I64(_) => "I64",
52 Self::F64(_) => "F64",
53 }
54 }
55
56 pub fn coerce_unsigned(&self) -> Option<u64> {
57 match self {
58 Self::U64(u) => Some(*u),
59 Self::I64(i) => (*i).try_into().ok(),
60 Self::F64(OrderedFloat(f))
61 if f.fract() == 0.0 && *f >= u64::MIN as f64 && *f <= u64::MAX as f64 =>
62 {
63 Some(*f as u64)
64 }
65 _ => None,
66 }
67 }
68
69 pub fn coerce_signed(&self) -> Option<i64> {
70 match self {
71 Self::I64(u) => Some(*u),
72 Self::U64(i) => (*i).try_into().ok(),
73 Self::F64(OrderedFloat(f))
74 if f.fract() == 0.0 && *f >= i64::MIN as f64 && *f <= i64::MAX as f64 =>
75 {
76 Some(*f as i64)
77 }
78 _ => None,
79 }
80 }
81
82 pub fn coerce_float(&self) -> Option<f64> {
83 match self {
84 Self::I64(u) => Some(*u as f64),
85 Self::U64(i) => Some(*i as f64),
86 Self::F64(OrderedFloat(f)) => Some(*f),
87 _ => None,
88 }
89 }
90}