haystack_types/
h_val.rs

1use crate::common::{ZincWriter,ZincReader,JsonWriter,TrioWriter};
2use crate::io::HBox;
3use crate::{io, NumTrait};
4use std::fmt::{self,Display,Formatter,Debug};
5use core::str::FromStr;
6use num::Float;
7
8use nom::IResult;
9
10use crate::{h_bool::HBool, h_null::HNull, h_na::HNA,
11    h_marker::HMarker, h_remove::HRemove, h_number::HNumber,
12    h_date::HDate, h_datetime::HDateTime, h_time::HTime,
13    h_coord::HCoord, h_str::HStr, h_uri::HUri, h_ref::HRef, h_dict::HDict,
14    h_list::HList, h_grid::HGrid};
15
16#[derive(Debug,PartialEq)]
17pub enum HType {
18    Null,
19    Marker,
20    Remove,
21    NA,
22    Bool,
23    Number,
24    Str,
25    Uri,
26    Ref,
27    Date,
28    Time,
29    DateTime,
30    Coord,
31    XStr,
32    List,
33    Dict,
34    Grid,
35}
36
37impl Display for HType {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        write!(f, "{:?}",self)
40    }
41}
42
43macro_rules! set_get_method {
44    ( $name: ident,$tt: ty ) => {
45        fn $name(&self) -> Option<&$tt> { Some(self) }
46    };
47    ( $name: ident,$tt: ty, $lt: lifetime ) => {
48        fn $name(&self) -> Option<&$tt<$lt>> { Some(self) }
49    };
50}
51
52macro_rules! set_trait_get_method {
53    ( $name: ident,$tt: ty ) => {
54        fn $name(&self) -> Option<&$tt> { None }
55    };
56    ( $name:ident, $tt:ident, $lt:lifetime, $t:ty ) => {
57        fn $name(&$lt self) -> Option<&$lt $tt<$lt,$t>> { None }
58    };
59}
60
61macro_rules! set_trait_eq_method {
62    ( $get_method: ident, $lt: lifetime, $FT: tt ) => {
63        fn _eq(&self, other: &dyn HVal<$lt,$FT>) -> bool {
64            if let Some(other_obj) = other.$get_method() {
65                return self == other_obj
66            }
67            return false
68        }
69    }
70}
71
72pub trait HVal<'a,T: NumTrait + 'a> {
73    fn to_zinc(&self, buf: &mut String) -> fmt::Result;
74    fn to_json(&self, buf: &mut String) -> fmt::Result;
75    fn haystack_type(&self) -> HType;
76
77    fn _eq(&self, other: &dyn HVal<'a,T>) -> bool;
78
79    set_trait_get_method!(get_null_val, HNull);
80    set_trait_get_method!(get_marker_val, HMarker);
81    set_trait_get_method!(get_remove_val, HRemove);
82    set_trait_get_method!(get_na_val, HNA);
83    set_trait_get_method!(get_bool_val, HBool);
84    set_trait_get_method!(get_string_val, HStr);
85    set_trait_get_method!(get_uri_val, HUri);
86    set_trait_get_method!(get_coord_val, HCoord<T>);
87    set_trait_get_method!(get_datetime_val, HDateTime);
88    set_trait_get_method!(get_date_val, HDate);
89    set_trait_get_method!(get_time_val, HTime);
90    set_trait_get_method!(get_number_val, HNumber<T>);
91    set_trait_get_method!(get_ref_val, HRef);
92    set_trait_get_method!(get_dict_val, HDict,'a,T);
93    set_trait_get_method!(get_list_val, HList,'a,T);
94    set_trait_get_method!(get_grid_val, HGrid,'a,T);
95}
96
97impl <'a,T: NumTrait + 'a>Display for dyn HVal<'a,T> {
98    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99        let self_as_hval: &(dyn HVal<'a, T> + 'a) = self;
100        write!(f, "{}(",self_as_hval.haystack_type())?;
101        let mut buf = String::new();
102        HVal::to_zinc(self_as_hval, &mut buf)?;
103        write!(f, "{})",buf)
104    }
105}
106
107impl <'a,T: NumTrait + 'a>Debug for dyn HVal<'a,T> {
108    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109        write!(f, "{}",self)
110    }
111}
112
113impl <'a,T: NumTrait + 'a>PartialEq for dyn HVal<'a,T> {
114    fn eq(&self, other: &dyn HVal<'a,T>) -> bool {
115        // TODO: Implement equality testing for HVal
116        if self.haystack_type() == other.haystack_type() {
117            return self._eq(other);
118        };
119        false
120    }
121}
122
123impl <'a,T: NumTrait + 'a>ZincWriter<'a,T> for dyn HVal<'a,T> + 'a {
124    fn to_zinc(&self, buf: &mut String) -> fmt::Result { self.to_zinc(buf) }
125}
126
127impl <'a,T: NumTrait + 'a>ZincReader<'a,T> for dyn HVal<'a,T> {
128    fn parse<'b>(buf: &'b str) -> IResult<&'b str, HBox<'a,T>>
129    where
130        'a: 'b
131    {
132        io::parse::zinc::literal::<T>(buf)
133    }
134}
135
136impl <'a,T: NumTrait + 'a>Display for dyn ZincWriter<'a,T> {
137    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
138        let mut buf = String::new();
139        self.to_zinc(&mut buf)?;
140        write!(f, "{}", buf)
141    }
142}
143
144impl <'a,T: NumTrait + 'a>JsonWriter<'a,T> for dyn HVal<'a,T> {
145    fn to_json(&self, buf: &mut String) -> fmt::Result { self.to_json(buf) }
146}
147
148impl <'a,T: NumTrait + 'a>Display for dyn JsonWriter<'a,T> {
149    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
150        let mut buf = String::new();
151        self.to_json(&mut buf)?;
152        write!(f, "{}", buf)
153    }
154}
155
156impl <'a,T: NumTrait + 'a>TrioWriter<'a,T> for dyn HVal<'a,T> {
157    fn to_trio(&self, buf: &mut String) -> fmt::Result { self.to_zinc(buf) }
158}
159
160impl <'a,T: NumTrait + 'a>Display for dyn TrioWriter<'a,T> {
161    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
162        let mut buf = String::new();
163        self.to_trio(&mut buf)?;
164        write!(f, "{}", buf)
165    }
166}