Skip to main content

xq/
value.rs

1use std::{
2    borrow::Borrow,
3    cmp::Ordering,
4    collections::HashMap,
5    fmt::{Debug, Display, Formatter},
6    hash::{Hash, Hasher},
7    ops::Deref,
8    rc::Rc,
9    slice::SliceIndex,
10};
11
12use derive_more::{DebugCustom, Display, Index, IndexMut, IntoIterator, IsVariant, Unwrap};
13use itertools::Itertools;
14use num::Float;
15use serde::{
16    de::{Error, MapAccess, SeqAccess, Visitor},
17    ser::{SerializeMap, SerializeSeq},
18    Deserialize, Deserializer, Serialize, Serializer,
19};
20
21use crate::Number;
22
23type Vector = Vec<Value>;
24type Map = HashMap<RcString, Value>;
25pub type RcString = Rc<String>;
26
27#[derive(
28    Clone, Eq, PartialEq, Hash, Default, DebugCustom, Display, IntoIterator, Index, IndexMut,
29)]
30#[debug(fmt = "{_0:?}")]
31#[display(fmt = "{_0:?}")]
32pub struct Array(#[into_iterator(owned, ref, ref_mut)] Vector);
33
34#[derive(Clone, Eq, PartialEq, Default, DebugCustom, Display, IntoIterator, Index, IndexMut)]
35#[debug(fmt = "{_0:?}")]
36#[display(fmt = "{_0:?}")]
37pub struct Object(#[into_iterator(owned, ref, ref_mut)] Map);
38
39#[allow(clippy::derived_hash_with_manual_eq)] // HashMap::eq is implemented properly.
40impl Hash for Object {
41    fn hash<H: Hasher>(&self, state: &mut H) {
42        for (key, value) in self.0.iter().sorted_unstable_by_key(|e| e.0) {
43            key.hash(state);
44            value.hash(state);
45        }
46    }
47}
48
49impl Array {
50    pub fn new() -> Self {
51        Default::default()
52    }
53
54    pub fn with_capacity(capacity: usize) -> Self {
55        Self(Vector::with_capacity(capacity))
56    }
57
58    pub fn from_vec(v: Vector) -> Self {
59        Self(v)
60    }
61
62    pub fn is_empty(&self) -> bool {
63        self.0.is_empty()
64    }
65
66    pub fn len(&self) -> usize {
67        self.0.len()
68    }
69
70    pub fn push<V>(&mut self, value: V)
71    where
72        V: Into<Value>,
73    {
74        self.0.push(value.into())
75    }
76
77    pub fn extend<I: IntoIterator<Item = Value>>(&mut self, iter: I) {
78        self.0.extend(iter);
79    }
80
81    pub fn get<I: SliceIndex<[Value]>>(&self, index: I) -> Option<&I::Output> {
82        self.0.get(index)
83    }
84
85    pub fn remove(&mut self, index: usize) -> Value {
86        self.0.remove(index)
87    }
88
89    pub fn split_off(&mut self, index: usize) -> Self {
90        Self(self.0.split_off(index))
91    }
92}
93
94impl Object {
95    pub fn new() -> Self {
96        Default::default()
97    }
98
99    pub fn with_capacity(capacity: usize) -> Self {
100        Self(Map::with_capacity(capacity))
101    }
102
103    pub fn is_empty(&self) -> bool {
104        self.0.is_empty()
105    }
106
107    pub fn len(&self) -> usize {
108        self.0.len()
109    }
110
111    pub fn iter(&self) -> impl Iterator<Item = (&RcString, &Value)> {
112        self.0.iter()
113    }
114
115    pub fn insert<K, V>(&mut self, key: K, value: V) -> Option<Value>
116    where
117        K: Into<RcString>,
118        V: Into<Value>,
119    {
120        self.0.insert(key.into(), value.into())
121    }
122
123    pub fn extend<T: IntoIterator<Item = (RcString, Value)>>(&mut self, iter: T) {
124        self.0.extend(iter)
125    }
126
127    pub fn keys(&self) -> impl Iterator<Item = &RcString> {
128        self.0.keys()
129    }
130
131    pub fn get<Q>(&self, key: &Q) -> Option<&Value>
132    where
133        RcString: Borrow<Q>,
134        Q: ?Sized + Hash + Eq,
135    {
136        self.0.get(key)
137    }
138
139    pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut Value>
140    where
141        RcString: Borrow<Q>,
142        Q: ?Sized + Hash + Eq,
143    {
144        self.0.get_mut(key)
145    }
146
147    pub fn remove<Q>(&mut self, key: &Q) -> Option<Value>
148    where
149        RcString: Borrow<Q>,
150        Q: ?Sized + Hash + Eq,
151    {
152        self.0.remove(key)
153    }
154
155    pub fn entry(
156        &mut self,
157        key: RcString,
158    ) -> std::collections::hash_map::Entry<'_, RcString, Value> {
159        self.0.entry(key)
160    }
161}
162
163impl FromIterator<Value> for Array {
164    fn from_iter<T: IntoIterator<Item = Value>>(iter: T) -> Self {
165        Array(Vector::from_iter(iter))
166    }
167}
168
169impl FromIterator<(RcString, Value)> for Object {
170    fn from_iter<T: IntoIterator<Item = (RcString, Value)>>(iter: T) -> Self {
171        Object(Map::from_iter(iter))
172    }
173}
174
175impl Deref for Array {
176    type Target = [Value];
177
178    fn deref(&self) -> &Self::Target {
179        &self.0
180    }
181}
182
183#[derive(
184    Clone, Eq, PartialEq, Hash, derive_more::From, derive_more::TryInto, IsVariant, Unwrap,
185)]
186pub enum Value {
187    Null,
188    Boolean(bool),
189    Number(Number),
190    String(RcString),
191    Array(Rc<Array>),
192    Object(Rc<Object>),
193}
194
195impl From<String> for Value {
196    fn from(s: String) -> Self {
197        Self::String(RcString::new(s))
198    }
199}
200
201impl From<Array> for Value {
202    fn from(arr: Array) -> Self {
203        Self::Array(Rc::new(arr))
204    }
205}
206
207impl From<Object> for Value {
208    fn from(obj: Object) -> Self {
209        Self::Object(Rc::new(obj))
210    }
211}
212
213impl Debug for Value {
214    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
215        match self {
216            Value::Null => f.write_str("null"),
217            Value::Boolean(v) => f.write_fmt(format_args!("{v:?}")),
218            Value::Number(v) => f.write_fmt(format_args!("{v:?}")),
219            Value::String(v) => f.write_fmt(format_args!("{v:?}")),
220            Value::Array(v) => f.write_fmt(format_args!("{:?}", v.as_ref())),
221            Value::Object(v) => f.write_fmt(format_args!("{:?}", v.as_ref())),
222        }
223    }
224}
225impl Display for Value {
226    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
227        match self {
228            Value::Null => f.write_str("null"),
229            Value::Boolean(v) => f.write_fmt(format_args!("{v:?}")),
230            Value::Number(v) => f.write_fmt(format_args!("{v:?}")),
231            Value::String(v) => f.write_fmt(format_args!("{v:?}")),
232            Value::Array(arr) => {
233                f.write_str("[")?;
234                let mut first = true;
235                for v in arr.as_ref() {
236                    if first {
237                        first = false;
238                    } else {
239                        f.write_str(", ")?;
240                    }
241                    Display::fmt(&v, f)?;
242                }
243                f.write_str("]")
244            }
245            Value::Object(obj) => {
246                f.write_str("{")?;
247                let mut first = true;
248                for (k, v) in obj.as_ref() {
249                    if first {
250                        first = false;
251                    } else {
252                        f.write_str(", ")?;
253                    }
254                    f.write_fmt(format_args!("{k}: {v}"))?;
255                }
256                f.write_str("}")
257            }
258        }
259    }
260}
261
262impl Value {
263    pub fn number<T: Into<Number>>(n: T) -> Self {
264        // TODO: Replace the caller with into
265        n.into().into()
266    }
267    pub fn string(s: String) -> Self {
268        // TODO: Replace the caller with into
269        s.into()
270    }
271}
272
273impl Serialize for Value {
274    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
275    where
276        S: Serializer,
277    {
278        match self {
279            Value::Null => serializer.serialize_none(),
280            Value::Boolean(v) => serializer.serialize_bool(*v),
281            Value::Number(v) => {
282                if v.is_finite() {
283                    v.serialize(serializer)
284                } else if v.is_nan() {
285                    serializer.serialize_none()
286                } else if v.is_sign_negative() {
287                    serializer.serialize_f64(f64::MIN)
288                } else {
289                    serializer.serialize_f64(f64::MAX)
290                }
291            }
292            Value::String(s) => serializer.serialize_str(s),
293            Value::Array(arr) => {
294                let mut seq = serializer.serialize_seq(Some(arr.len()))?;
295                for e in arr.as_ref() {
296                    seq.serialize_element::<Value>(e)?;
297                }
298                seq.end()
299            }
300            Value::Object(obj) => {
301                let mut map = serializer.serialize_map(Some(obj.len()))?;
302                for (k, v) in obj.as_ref() {
303                    map.serialize_entry::<String, Value>(k, v)?;
304                }
305                map.end()
306            }
307        }
308    }
309}
310
311impl<'de> Deserialize<'de> for Value {
312    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
313    where
314        D: Deserializer<'de>,
315    {
316        struct V;
317        impl<'de> Visitor<'de> for V {
318            type Value = Value;
319
320            fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
321                write!(
322                    formatter,
323                    "null, boolean, number, string, array, or map keyed with string"
324                )
325            }
326
327            fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
328            where
329                E: serde::de::Error,
330            {
331                Ok(v.into())
332            }
333
334            fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
335            where
336                E: serde::de::Error,
337            {
338                Ok(Value::number(v))
339            }
340
341            fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
342            where
343                E: serde::de::Error,
344            {
345                Ok(Value::number(v))
346            }
347
348            fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
349            where
350                E: serde::de::Error,
351            {
352                Ok(Value::number(v))
353            }
354
355            fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
356            where
357                E: serde::de::Error,
358            {
359                Ok(Value::number(v))
360            }
361
362            fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
363            where
364                E: serde::de::Error,
365            {
366                Ok(Value::number(v))
367            }
368
369            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
370            where
371                E: serde::de::Error,
372            {
373                Ok(v.to_string().into())
374            }
375
376            fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
377            where
378                E: serde::de::Error,
379            {
380                Ok(v.into())
381            }
382
383            fn visit_none<E>(self) -> Result<Self::Value, E>
384            where
385                E: serde::de::Error,
386            {
387                Ok(Value::Null)
388            }
389
390            fn visit_unit<E>(self) -> Result<Self::Value, E>
391            where
392                E: Error,
393            {
394                Ok(Value::Null)
395            }
396
397            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
398            where
399                A: SeqAccess<'de>,
400            {
401                let mut arr = if let Some(n) = seq.size_hint() {
402                    Array::with_capacity(n)
403                } else {
404                    Array::new()
405                };
406                while let Some(elem) = seq.next_element::<Value>()? {
407                    arr.push(elem);
408                }
409                Ok(arr.into())
410            }
411
412            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
413            where
414                A: MapAccess<'de>,
415            {
416                let mut obj = if let Some(n) = map.size_hint() {
417                    Object::with_capacity(n)
418                } else {
419                    Object::new()
420                };
421                while let Some((key, value)) = map.next_entry::<String, Value>()? {
422                    obj.insert(key, value);
423                }
424                Ok(obj.into())
425            }
426        }
427        deserializer.deserialize_any(V)
428    }
429}
430
431impl PartialOrd for Value {
432    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
433        Some(Self::cmp(self, other))
434    }
435}
436
437impl Ord for Value {
438    fn cmp(&self, other: &Self) -> Ordering {
439        use Ordering::*;
440        use Value::*;
441        fn type_ord(value: &Value) -> u8 {
442            match value {
443                Null => 0,
444                Boolean(_) => 1,
445                Number(_) => 2,
446                String(_) => 3,
447                Array(_) => 4,
448                Object(_) => 5,
449            }
450        }
451        if let res @ (Less | Greater) = type_ord(self).cmp(&type_ord(other)) {
452            return res;
453        }
454        match (&self, &other) {
455            (Null, Null) => Equal,
456            (Boolean(lhs), Boolean(rhs)) => Ord::cmp(lhs, rhs),
457            (Number(lhs), Number(rhs)) => Ord::cmp(&lhs, &rhs),
458            (String(lhs), String(rhs)) => Ord::cmp(&lhs, &rhs),
459            (Array(lhs), Array(rhs)) => Iterator::cmp(lhs.iter(), rhs.iter()),
460            (Object(lhs), Object(rhs)) => {
461                let lhs_keys = lhs.keys().sorted_unstable().collect_vec();
462                let rhs_keys = rhs.keys().sorted_unstable().collect_vec();
463                if let res @ (Less | Greater) = Iterator::cmp(lhs_keys.iter(), rhs_keys.iter()) {
464                    return res;
465                }
466                for key in lhs_keys {
467                    if let res @ (Less | Greater) = Ord::cmp(&lhs.get(key), &rhs.get(key)) {
468                        return res;
469                    }
470                }
471                Equal
472            }
473            (Null | Boolean(_) | Number(_) | String(_) | Array(_) | Object(_), _) => {
474                unreachable!()
475            }
476        }
477    }
478}