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 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}