litl_val/
val.rs

1use std::{
2    fmt::Debug,
3    hash::{Hash, Hasher},
4    ops::Index,
5};
6
7use deepsize::DeepSizeOf;
8use ordered_float::NotNan;
9
10use super::{key_e::KeyE, slim_boxed_slice::SlimBoxedSlice, val_ref::ValRef, Map, ValE};
11
12pub struct Val(pub(crate) f64);
13
14impl Val {
15    #[inline]
16    pub fn str(s: &str) -> Val {
17        ValE::str(s).into()
18    }
19
20    #[inline]
21    pub fn string(s: String) -> Val {
22        ValE::string(s).into()
23    }
24
25    #[inline]
26    pub fn number(n: f64) -> Val {
27        ValE::Number(NotNan::new(n).unwrap()).into()
28    }
29
30    #[inline]
31    pub fn bool(b: bool) -> Val {
32        ValE::Bool(b).into()
33    }
34
35    #[inline]
36    pub fn null() -> Val {
37        ValE::Null.into()
38    }
39
40    #[inline]
41    pub fn array<V: Into<Val>, I: IntoIterator<Item = V>>(items: I) -> Val {
42        ValE::Array(SlimBoxedSlice::from_vec(
43            items.into_iter().map(Into::into).collect::<Vec<_>>(),
44        ))
45        .into()
46    }
47
48    #[inline]
49    pub fn object<K: ToString, V: Into<Val>, I: IntoIterator<Item = (K, V)>>(items: I) -> Val {
50        ValE::Object(Map::new(
51            items
52                .into_iter()
53                .map(|(k, v)| (KeyE::string(k.to_string()).into(), v.into()))
54                .collect::<Vec<_>>(),
55        ))
56        .into()
57    }
58
59    #[inline]
60    pub fn as_str(&self) -> Option<&str> {
61        self.direct_ref().as_str()
62    }
63
64    #[inline]
65    pub fn is_null(&self) -> bool {
66        matches!(self.direct_ref(), ValRef::Null)
67    }
68
69    #[inline]
70    pub fn get<S: AsRef<str>>(&self, key: S) -> Option<&Val> {
71        self.direct_ref().get(key)
72    }
73}
74
75impl PartialEq for Val {
76    fn eq(&self, other: &Self) -> bool {
77        self.direct_ref() == other.direct_ref()
78    }
79}
80
81impl Eq for Val {}
82
83impl PartialOrd for Val {
84    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
85        self.direct_ref().partial_cmp(&other.direct_ref())
86    }
87}
88
89impl Ord for Val {
90    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
91        self.direct_ref().cmp(&other.direct_ref())
92    }
93}
94
95impl Debug for Val {
96    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97        self.direct_ref().fmt(f)
98    }
99}
100
101impl Clone for Val {
102    #[inline]
103    fn clone(&self) -> Self {
104        match self.direct_ref() {
105            ValRef::Null => ValE::Null,
106            ValRef::Bool(b) => ValE::Bool(b),
107            ValRef::Number(n) => ValE::Number(n),
108            ValRef::String(s) => ValE::str(s),
109            ValRef::Array(a) => ValE::Array(SlimBoxedSlice::from_vec(a.to_vec())),
110            ValRef::Object(o) => ValE::Object(Map::clone_from_ref(&o)),
111        }
112        .into()
113    }
114}
115
116impl Hash for Val {
117    #[inline]
118    fn hash<H: Hasher>(&self, state: &mut H) {
119        self.direct_ref().hash(state)
120    }
121}
122
123impl Index<usize> for Val {
124    type Output = Val;
125
126    #[inline]
127    fn index(&self, index: usize) -> &Self::Output {
128        match self.direct_ref() {
129            ValRef::Array(a) => &a[index],
130            _ => panic!("Tried to index into Val that is not an array"),
131        }
132    }
133}
134
135impl DeepSizeOf for Val {
136    fn deep_size_of_children(&self, context: &mut deepsize::Context) -> usize {
137        let unsafe_clone = Val(self.0).into();
138        let size = match &unsafe_clone {
139            ValE::Bool(_) => 8,
140            ValE::Null => 8,
141            ValE::Number(_) => 8,
142            ValE::ShortString(_) => 8,
143            ValE::LongString(s) => s.deep_size_of_children(context),
144            ValE::Array(a) => a.deep_size_of_children(context),
145            ValE::Object(o) => o.deep_size_of_children(context),
146        };
147        std::mem::forget(unsafe_clone);
148        size
149    }
150}