Skip to main content

hessian_rs/
value.rs

1extern crate ordered_float;
2
3use ordered_float::OrderedFloat;
4use std::cmp::Ordering;
5use std::collections::HashMap;
6use std::fmt;
7use std::hash::{Hash, Hasher};
8use std::ops::{Deref, DerefMut};
9
10/// class definition
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct Definition {
13    pub name: String,
14    pub fields: Vec<String>,
15}
16
17/// hessian 2.0 list
18#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
19pub enum List {
20    Typed(String, Vec<Value>),
21    Untyped(Vec<Value>),
22}
23
24impl List {
25    pub fn r#type(&self) -> Option<&str> {
26        match self {
27            List::Typed(ref typ, _) => Some(typ),
28            List::Untyped(_) => None,
29        }
30    }
31
32    pub fn value(&self) -> &[Value] {
33        match self {
34            List::Typed(_, val) => val,
35            List::Untyped(val) => val,
36        }
37    }
38
39    pub fn value_mut(&mut self) -> &mut [Value] {
40        match self {
41            List::Typed(_, val) => val,
42            List::Untyped(val) => val,
43        }
44    }
45}
46
47impl From<Vec<Value>> for List {
48    fn from(val: Vec<Value>) -> Self {
49        Self::Untyped(val)
50    }
51}
52
53impl From<(String, Vec<Value>)> for List {
54    fn from(val: (String, Vec<Value>)) -> Self {
55        Self::Typed(val.0, val.1)
56    }
57}
58
59impl From<(&str, Vec<Value>)> for List {
60    fn from(val: (&str, Vec<Value>)) -> Self {
61        Self::Typed(val.0.to_string(), val.1)
62    }
63}
64
65impl Deref for List {
66    type Target = [Value];
67
68    fn deref(&self) -> &Self::Target {
69        self.value()
70    }
71}
72
73impl DerefMut for List {
74    fn deref_mut(&mut self) -> &mut Self::Target {
75        self.value_mut()
76    }
77}
78
79/// hessian 2.0 map
80#[derive(Clone, Debug, PartialEq, Eq)]
81pub enum Map {
82    Typed(String, HashMap<Value, Value>),
83    Untyped(HashMap<Value, Value>),
84}
85
86impl Map {
87    pub fn r#type(&self) -> Option<&str> {
88        match self {
89            Map::Typed(ref typ, _) => Some(typ),
90            Map::Untyped(_) => None,
91        }
92    }
93
94    pub fn value(&self) -> &HashMap<Value, Value> {
95        match self {
96            Map::Typed(_, val) => val,
97            Map::Untyped(val) => val,
98        }
99    }
100
101    pub fn value_mut(&mut self) -> &mut HashMap<Value, Value> {
102        match self {
103            Map::Typed(_, val) => val,
104            Map::Untyped(val) => val,
105        }
106    }
107}
108
109impl From<HashMap<Value, Value>> for Map {
110    fn from(val: HashMap<Value, Value>) -> Self {
111        Self::Untyped(val)
112    }
113}
114
115impl From<(String, HashMap<Value, Value>)> for Map {
116    fn from(val: (String, HashMap<Value, Value>)) -> Self {
117        Self::Typed(val.0, val.1)
118    }
119}
120
121impl From<(&str, HashMap<Value, Value>)> for Map {
122    fn from(val: (&str, HashMap<Value, Value>)) -> Self {
123        Self::Typed(val.0.to_string(), val.1)
124    }
125}
126
127impl Deref for Map {
128    type Target = HashMap<Value, Value>;
129
130    fn deref(&self) -> &Self::Target {
131        self.value()
132    }
133}
134
135impl DerefMut for Map {
136    fn deref_mut(&mut self) -> &mut Self::Target {
137        self.value_mut()
138    }
139}
140
141/// hessian 2.0 value type
142#[derive(Clone, Debug, PartialEq)]
143pub enum Value {
144    /// null
145    Null,
146    // ClassDef,
147    /// boolean
148    Bool(bool),
149    /// 32-bit int
150    Int(i32),
151    /// 64-bit int
152    Long(i64),
153    /// 64-bit double
154    Double(f64),
155    /// 64-bit millisecond date
156    Date(i64),
157    /// raw binary data
158    Bytes(Vec<u8>),
159    /// UTF8-encoded string
160    String(String),
161    /// shared and circular object references
162    Ref(u32),
163    // list for lists and arrays
164    List(List),
165    /// map for maps and dictionaries
166    Map(Map),
167}
168
169impl Value {
170    /// Takes the value out of the `Value`, leaving a `Null` in its place.
171    pub fn take(&mut self) -> Self {
172        std::mem::replace(self, Value::Null)
173    }
174
175    /// If the `Value` is a `Null`, returns `()`. Returns `None` otherwise.
176    pub fn as_null(&self) -> Option<()> {
177        match self {
178            Value::Null => Some(()),
179            _ => None,
180        }
181    }
182
183    pub fn is_null(&self) -> bool {
184        self.as_null().is_some()
185    }
186
187    pub fn as_bool(&self) -> Option<bool> {
188        match *self {
189            Value::Bool(b) => Some(b),
190            _ => None,
191        }
192    }
193
194    pub fn is_bool(&self) -> bool {
195        self.as_bool().is_some()
196    }
197
198    pub fn as_int(&self) -> Option<i32> {
199        match *self {
200            Value::Int(i) => Some(i),
201            _ => None,
202        }
203    }
204
205    pub fn is_int(&self) -> bool {
206        self.as_int().is_some()
207    }
208
209    pub fn as_long(&self) -> Option<i64> {
210        match *self {
211            Value::Long(l) => Some(l),
212            _ => None,
213        }
214    }
215
216    pub fn is_long(&self) -> bool {
217        self.as_long().is_some()
218    }
219
220    pub fn as_double(&self) -> Option<f64> {
221        match *self {
222            Value::Double(f) => Some(f),
223            _ => None,
224        }
225    }
226
227    pub fn is_double(&self) -> bool {
228        self.as_double().is_some()
229    }
230
231    pub fn as_date(&self) -> Option<i64> {
232        match *self {
233            Value::Date(d) => Some(d),
234            _ => None,
235        }
236    }
237
238    pub fn is_date(&self) -> bool {
239        self.as_date().is_some()
240    }
241
242    pub fn as_bytes(&self) -> Option<&[u8]> {
243        match self {
244            Value::Bytes(bs) => Some(bs),
245            _ => None,
246        }
247    }
248
249    pub fn is_bytes(&self) -> bool {
250        self.as_bytes().is_some()
251    }
252
253    pub fn as_str(&self) -> Option<&str> {
254        match self {
255            Value::String(s) => Some(s),
256            _ => None,
257        }
258    }
259
260    pub fn is_str(&self) -> bool {
261        self.as_str().is_some()
262    }
263
264    pub fn as_ref(&self) -> Option<u32> {
265        match *self {
266            Value::Ref(r) => Some(r),
267            _ => None,
268        }
269    }
270
271    pub fn is_ref(&self) -> bool {
272        self.as_ref().is_some()
273    }
274
275    pub fn as_list(&self) -> Option<&List> {
276        match self {
277            Value::List(l) => Some(l),
278            _ => None,
279        }
280    }
281
282    pub fn as_list_mut(&mut self) -> Option<&mut List> {
283        match self {
284            Value::List(l) => Some(l),
285            _ => None,
286        }
287    }
288
289    pub fn is_list(&self) -> bool {
290        self.as_int().is_some()
291    }
292
293    pub fn as_map(&self) -> Option<&Map> {
294        match self {
295            Value::Map(m) => Some(m),
296            _ => None,
297        }
298    }
299
300    pub fn as_map_mut(&mut self) -> Option<&mut Map> {
301        match self {
302            Value::Map(m) => Some(m),
303            _ => None,
304        }
305    }
306
307    pub fn is_map(&self) -> bool {
308        self.as_map().is_some()
309    }
310}
311
312impl PartialOrd for Value {
313    fn partial_cmp(&self, other: &Value) -> Option<Ordering> {
314        Some(self.cmp(&other))
315    }
316}
317
318impl Eq for Value {}
319
320// Although we impl Hash for Map and List, we shouldn't use container type as key
321impl Hash for Value {
322    fn hash<H: Hasher>(&self, state: &mut H) {
323        use self::Value::*;
324
325        match *self {
326            Null => ().hash(state),
327            Bool(b) => b.hash(state),
328            Int(i) => i.hash(state),
329            Long(l) => l.hash(state),
330            Double(d) => OrderedFloat(d).hash(state),
331            Date(d) => d.hash(state),
332            Bytes(ref bytes) => bytes.hash(state),
333            String(ref s) => s.hash(state),
334            Ref(i) => i.hash(state),
335            List(ref l) => l.hash(state),
336            // Hash each key-value is too expensive.
337            Map(ref m) => std::ptr::hash(m, state),
338        }
339    }
340}
341
342impl Ord for Value {
343    fn cmp(&self, other: &Value) -> Ordering {
344        use self::Value::*;
345
346        match *self {
347            Null => match *other {
348                Null => Ordering::Equal,
349                _ => Ordering::Less,
350            },
351            Bool(b) => match *other {
352                Null => Ordering::Greater,
353                Int(i) => (b as i32).cmp(&i),
354                Long(l) => (b as i64).cmp(&l),
355                Double(d) => float_ord(b as i64 as f64, d),
356                Date(d) => (b as i64).cmp(&d),
357                _ => Ordering::Less,
358            },
359            Int(i) => match *other {
360                Null => Ordering::Greater,
361                Bool(b) => i.cmp(&(b as i32)),
362                Int(i2) => i.cmp(&i2),
363                Long(l) => (i as i64).cmp(&l),
364                Double(d) => float_ord(i as f64, d),
365                Date(d) => (i as i64).cmp(&d),
366                _ => Ordering::Less,
367            },
368            Long(l) => match *other {
369                Null => Ordering::Greater,
370                Bool(b) => l.cmp(&(b as i64)),
371                Int(i2) => l.cmp(&(i2 as i64)),
372                Long(l2) => l.cmp(&l2),
373                Double(d) => float_ord(l as f64, d),
374                Date(d) => l.cmp(&d),
375                _ => Ordering::Less,
376            },
377            Double(d) => match *other {
378                Null => Ordering::Greater,
379                Bool(b) => float_ord(d, b as i64 as f64),
380                Int(i) => float_ord(d, i as f64),
381                Long(l) => float_ord(d, l as f64),
382                Double(d2) => float_ord(d, d2),
383                Date(d2) => float_ord(d, d2 as f64),
384                _ => Ordering::Less,
385            },
386            Date(d) => match *other {
387                Null => Ordering::Greater,
388                Bool(b) => d.cmp(&(b as i64)),
389                Int(i2) => d.cmp(&(i2 as i64)),
390                Long(l2) => d.cmp(&l2),
391                Double(d2) => float_ord(d as f64, d2),
392                Date(d2) => d.cmp(&d2),
393                _ => Ordering::Less,
394            },
395            Bytes(ref bs) => match *other {
396                String(_) | List(_) | Ref(_) | Map(_) => Ordering::Less,
397                Bytes(ref bs2) => bs.cmp(bs2),
398                _ => Ordering::Greater,
399            },
400            String(ref s) => match *other {
401                Ref(_) | List(_) | Map(_) => Ordering::Less,
402                String(ref s2) => s.cmp(s2),
403                _ => Ordering::Greater,
404            },
405            Ref(i) => match *other {
406                List(_) | Map(_) => Ordering::Less,
407                Ref(i2) => i.cmp(&i2),
408                _ => Ordering::Greater,
409            },
410            List(ref l) => match other {
411                Map(_) => Ordering::Less,
412                List(l2) => l.cmp(l2),
413                _ => Ordering::Greater,
414            },
415            Map(ref m) => match other {
416                Map(m2) => {
417                    let mut v1: Vec<_> = m.iter().collect();
418                    let mut v2: Vec<_> = m2.iter().collect();
419                    v1.sort_by(|l_iter, r_iter| l_iter.0.cmp(r_iter.0));
420                    v2.sort_by(|l_iter, r_iter| l_iter.0.cmp(r_iter.0));
421                    v1.cmp(&v2)
422                }
423                _ => Ordering::Greater,
424            },
425        }
426    }
427}
428
429fn float_ord(f: f64, g: f64) -> Ordering {
430    match f.partial_cmp(&g) {
431        Some(o) => o,
432        None => Ordering::Less,
433    }
434}
435
436pub trait ToHessian {
437    fn to_hessian(self) -> Value;
438}
439
440macro_rules! to_hessian (
441    ($t:ty, $v:expr) => (
442        impl ToHessian for $t {
443        fn to_hessian(self) -> Value {
444            $v(self)
445        }
446    }
447    );
448);
449
450to_hessian!(bool, Value::Bool);
451to_hessian!(i32, Value::Int);
452to_hessian!(i64, Value::Long);
453to_hessian!(f64, Value::Double);
454to_hessian!(String, Value::String);
455to_hessian!(Vec<u8>, Value::Bytes);
456
457impl ToHessian for () {
458    fn to_hessian(self) -> Value {
459        Value::Null
460    }
461}
462
463impl<'a> ToHessian for &'a str {
464    fn to_hessian(self) -> Value {
465        Value::String(self.to_owned())
466    }
467}
468
469impl<'a> ToHessian for &'a String {
470    fn to_hessian(self) -> Value {
471        Value::String(self.to_owned())
472    }
473}
474
475impl<'a> ToHessian for &'a [u8] {
476    fn to_hessian(self) -> Value {
477        Value::Bytes(self.to_owned())
478    }
479}
480
481impl<'a> ToHessian for &'a Vec<u8> {
482    fn to_hessian(self) -> Value {
483        Value::Bytes(self.to_owned())
484    }
485}
486
487impl<K, V> ToHessian for HashMap<K, V>
488where
489    K: ToHessian,
490    V: ToHessian,
491{
492    fn to_hessian(self) -> Value {
493        let kv: HashMap<Value, Value> = self
494            .into_iter()
495            .map(|(k, v)| (k.to_hessian(), v.to_hessian()))
496            .collect();
497        Value::Map(kv.into())
498    }
499}
500
501impl<K, V> ToHessian for (String, HashMap<K, V>)
502where
503    K: ToHessian,
504    V: ToHessian,
505{
506    fn to_hessian(self) -> Value {
507        let (typ, kv) = self;
508        let kv: HashMap<Value, Value> = kv
509            .into_iter()
510            .map(|(k, v)| (k.to_hessian(), v.to_hessian()))
511            .collect();
512        Value::Map((typ, kv.into()).into())
513    }
514}
515
516impl<K, V> ToHessian for (&str, HashMap<K, V>)
517where
518    K: ToHessian,
519    V: ToHessian,
520{
521    fn to_hessian(self) -> Value {
522        let (typ, kv) = self;
523        let kv: HashMap<Value, Value> = kv
524            .into_iter()
525            .map(|(k, v)| (k.to_hessian(), v.to_hessian()))
526            .collect();
527        Value::Map((typ, kv.into()).into())
528    }
529}
530
531impl<T: ToHessian> From<T> for Value {
532    fn from(val: T) -> Self {
533        val.to_hessian()
534    }
535}
536
537impl fmt::Display for Value {
538    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
539        match *self {
540            Value::Null => write!(f, "None"),
541            Value::Bool(b) => write!(f, "{}", if b { "True" } else { "False" }),
542            Value::Int(ref i) => write!(f, "{}", i),
543            Value::Double(ref v) => write!(f, "{}", v),
544            Value::Date(v) => write!(f, "Date({})", v),
545            Value::Bytes(ref b) => write!(f, "b{:?}", b), //
546            Value::String(ref s) => write!(f, "{:?}", s),
547            Value::List(ref l) => {
548                write!(f, "[")?;
549                for (inx, v) in l.iter().enumerate() {
550                    if inx < l.len() - 1 {
551                        write!(f, "{}, ", v)?;
552                    } else {
553                        write!(f, "{}", v)?;
554                    }
555                }
556                write!(f, "]")
557            }
558            Value::Map(ref m) => {
559                write!(f, "{{")?;
560                for (key, value) in m.iter() {
561                    write!(f, "{} : {},", key, value)?;
562                }
563                write!(f, "}}")
564            }
565            _ => write!(f, "{}", "<Unknown Type>"),
566        }
567    }
568}