1use std::fmt;
2
3use serde_json::Number;
4
5#[derive(Debug, Clone)]
15pub enum JsonScalar {
16 Null,
18 Bool(bool),
20 Number(Number),
22 String(String),
24 Undefined,
26}
27
28impl JsonScalar {
29 #[must_use]
31 pub fn from_integer(value: i64) -> Self {
32 Self::Number(Number::from(value))
33 }
34
35 #[must_use]
39 pub fn from_float(value: f64) -> Option<Self> {
40 Number::from_f64(value).map(Self::Number)
41 }
42}
43
44impl PartialEq for JsonScalar {
45 fn eq(&self, other: &Self) -> bool {
46 match (self, other) {
47 (Self::Null, Self::Null) | (Self::Undefined, Self::Undefined) => true,
48 (Self::Bool(left), Self::Bool(right)) => left == right,
49 (Self::String(left), Self::String(right)) => left == right,
50 (Self::Number(left), Self::Number(right)) => numbers_equal(left, right),
51 _ => false,
52 }
53 }
54}
55
56impl fmt::Display for JsonScalar {
57 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
58 match self {
59 Self::Null => formatter.write_str("null"),
60 Self::Bool(value) => write!(formatter, "{value}"),
61 Self::Number(value) => write!(formatter, "{value}"),
62 Self::String(value) => write!(formatter, "{value:?}"),
63 Self::Undefined => formatter.write_str("undefined"),
64 }
65 }
66}
67
68impl From<bool> for JsonScalar {
69 fn from(value: bool) -> Self {
70 Self::Bool(value)
71 }
72}
73
74impl From<&str> for JsonScalar {
75 fn from(value: &str) -> Self {
76 Self::String(value.to_owned())
77 }
78}
79
80impl From<String> for JsonScalar {
81 fn from(value: String) -> Self {
82 Self::String(value)
83 }
84}
85
86fn numbers_equal(left: &Number, right: &Number) -> bool {
87 if let (Some(left), Some(right)) = (left.as_i64(), right.as_i64()) {
88 return left == right;
89 }
90 if let (Some(left), Some(right)) = (left.as_u64(), right.as_u64()) {
91 return left == right;
92 }
93 match (left.as_f64(), right.as_f64()) {
94 (Some(left), Some(right)) => left == right,
95 _ => false,
96 }
97}