libhaystack/haystack/val/
value.rs1use crate::haystack::val::boolean::*;
4use crate::haystack::val::coord::*;
5use crate::haystack::val::date::*;
6use crate::haystack::val::datetime::*;
7use crate::haystack::val::dict::*;
8use crate::haystack::val::grid::*;
9use crate::haystack::val::list::*;
10use crate::haystack::val::number::*;
11use crate::haystack::val::reference::*;
12use crate::haystack::val::string::*;
13use crate::haystack::val::symbol::*;
14use crate::haystack::val::time::*;
15use crate::haystack::val::uri::*;
16use crate::haystack::val::xstr::*;
17use crate::units::Unit;
18use std::fmt::{Display, Formatter};
19use std::hash::Hash;
20
21#[derive(PartialOrd, Eq, Ord, Clone, Debug, Default)]
67pub enum Value {
68 #[default]
70 Null,
71 Remove,
73 Marker,
75 Bool(Bool),
77 Na,
79 Number(Number),
81 Str(Str),
83 Uri(Uri),
85 Ref(Ref),
87 Symbol(Symbol),
89 Date(Date),
91 Time(Time),
93 DateTime(DateTime),
95 Coord(Coord),
97 XStr(XStr),
99 List(List),
101 Dict(Dict),
103 Grid(Grid),
105}
106
107impl Value {
111 pub fn is_null(&self) -> bool {
113 matches!(self, Value::Null)
114 }
115
116 pub fn has_value(&self) -> bool {
118 !self.is_null()
119 }
120
121 pub fn make_remove() -> Value {
123 Value::Remove
124 }
125
126 pub fn is_remove(&self) -> bool {
128 matches!(self, Value::Remove)
129 }
130
131 pub fn make_marker() -> Value {
133 Value::Marker
134 }
135
136 pub fn is_marker(&self) -> bool {
138 matches!(self, Value::Marker)
139 }
140
141 pub fn make_bool(value: bool) -> Value {
143 Value::Bool(Bool::from(value))
144 }
145
146 pub fn make_true() -> Value {
148 Value::Bool(true.into())
149 }
150
151 pub fn is_true(&self) -> bool {
153 match self {
154 Value::Bool(v) => v.value,
155 _ => false,
156 }
157 }
158
159 pub fn is_false(&self) -> bool {
161 !self.is_true()
162 }
163
164 pub fn make_false() -> Value {
166 Value::Bool(false.into())
167 }
168
169 pub fn is_bool(&self) -> bool {
170 matches!(self, Value::Bool(_))
171 }
172
173 pub fn make_na() -> Value {
175 Value::Na
176 }
177
178 pub fn is_na(&self) -> bool {
180 matches!(self, Value::Na)
181 }
182
183 pub fn make_number(value: f64) -> Value {
185 Value::from(value)
186 }
187
188 pub fn make_int(value: i64) -> Value {
190 Value::from(value as f64)
191 }
192
193 pub fn make_number_unit(value: f64, unit: &'static Unit) -> Value {
195 Value::Number(Number::make_with_unit(value, unit))
196 }
197
198 pub fn is_number(&self) -> bool {
200 matches!(self, Value::Number(_))
201 }
202
203 pub fn make_str(value: &str) -> Value {
205 Value::from(value)
206 }
207 pub fn is_str(&self) -> bool {
209 matches!(self, Value::Str(_))
210 }
211
212 pub fn make_ref(value: &str) -> Value {
214 Value::from(Ref::from(value))
215 }
216
217 pub fn make_ref_gen() -> Value {
219 Value::from(Ref::gen())
220 }
221
222 pub fn make_ref_with_dis(value: &str, dis: &str) -> Value {
224 Value::from(Ref {
225 value: String::from(value),
226 dis: Some(String::from(dis)),
227 })
228 }
229
230 pub fn is_ref(&self) -> bool {
232 matches!(self, Value::Ref(_))
233 }
234
235 pub fn make_symbol(value: &str) -> Value {
237 Value::from(Symbol::from(value))
238 }
239
240 pub fn is_symbol(&self) -> bool {
242 matches!(self, Value::Symbol(_))
243 }
244
245 pub fn make_uri(value: &str) -> Value {
247 Value::from(Uri::from(value))
248 }
249
250 pub fn is_uri(&self) -> bool {
252 matches!(self, Value::Uri(_))
253 }
254
255 pub fn make_date(value: Date) -> Value {
257 Value::from(value)
258 }
259
260 pub fn is_date(&self) -> bool {
262 matches!(self, Value::Date(_))
263 }
264
265 pub fn make_time(value: Time) -> Value {
267 Value::from(value)
268 }
269
270 pub fn is_time(&self) -> bool {
272 matches!(self, Value::Time(_))
273 }
274
275 pub fn make_datetime(value: DateTime) -> Value {
277 Value::from(value)
278 }
279 pub fn make_datetime_from_iso(value: &str) -> Result<Value, String> {
281 let date_time = DateTime::parse_from_rfc3339(value)?;
282 Ok(Value::from(date_time))
283 }
284
285 pub fn is_datetime(&self) -> bool {
287 matches!(self, Value::DateTime(_))
288 }
289
290 pub fn make_coord(value: Coord) -> Value {
292 Value::from(value)
293 }
294
295 pub fn make_coord_from(lat: f64, long: f64) -> Value {
297 Value::from(Coord { lat, long })
298 }
299
300 pub fn is_coord(&self) -> bool {
302 matches!(self, Value::Coord(_))
303 }
304
305 pub fn make_xstr(value: XStr) -> Value {
307 Value::from(value)
308 }
309
310 pub fn make_xstr_from(typ: &str, value: &str) -> Value {
312 Value::from(XStr::make(typ, value))
313 }
314
315 pub fn is_xstr(&self) -> bool {
317 matches!(self, Value::XStr(_))
318 }
319
320 pub fn make_list(value: List) -> Value {
322 Value::from(value)
323 }
324
325 pub fn is_list(&self) -> bool {
327 matches!(self, Value::List(_))
328 }
329
330 pub fn make_dict(value: Dict) -> Value {
332 Value::from(value)
333 }
334
335 pub fn is_dict(&self) -> bool {
337 matches!(self, Value::Dict(_))
338 }
339
340 pub fn make_grid(value: Grid) -> Value {
342 Value::from(value)
343 }
344
345 pub fn make_grid_from_dicts(value: Vec<Dict>) -> Value {
347 Value::from(Grid::make_from_dicts(value))
348 }
349
350 pub fn is_grid(&self) -> bool {
352 matches!(self, Value::Grid(_))
353 }
354}
355
356impl Display for Value {
358 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
359 use crate::haystack::encoding::zinc::encode::ToZinc;
360 match self {
361 Value::Null => f.write_str("Null"),
362
363 Value::Remove => f.write_str("Remove"),
364
365 Value::Marker => f.write_str("Marker"),
366
367 Value::Bool(val) => f.write_str(if val.value { "true" } else { "false" }),
368
369 Value::Na => f.write_str("Na"),
370
371 Value::Number(_)
372 | Value::Str(_)
373 | Value::Ref(_)
374 | Value::Uri(_)
375 | Value::Symbol(_)
376 | Value::Date(_)
377 | Value::Time(_)
378 | Value::DateTime(_)
379 | Value::Coord(_)
380 | Value::XStr(_)
381 | Value::List(_)
382 | Value::Dict(_)
383 | Value::Grid(_) => match self.to_zinc_string() {
384 Ok(zinc) => f.write_str(&zinc),
385 Err(_) => Err(std::fmt::Error),
386 },
387 }
388 }
389}
390
391impl Hash for Value {
392 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
393 match self {
394 Value::Null => std::any::TypeId::of::<Value>().hash(state),
395
396 Value::Marker => super::marker::Marker.hash(state),
397 Value::Remove => super::remove::Remove.hash(state),
398 Value::Na => super::na::Na.hash(state),
399
400 Value::Bool(val) => val.hash(state),
401 Value::Number(val) => val.hash(state),
402 Value::Str(val) => val.hash(state),
403 Value::Ref(val) => val.hash(state),
404 Value::Uri(val) => val.hash(state),
405 Value::Symbol(val) => val.hash(state),
406 Value::Date(val) => val.hash(state),
407 Value::Time(val) => val.hash(state),
408 Value::DateTime(val) => val.hash(state),
409 Value::Coord(val) => val.hash(state),
410 Value::XStr(val) => val.hash(state),
411 Value::List(val) => val.hash(state),
412 Value::Dict(val) => val.hash(state),
413 Value::Grid(val) => val.hash(state),
414 }
415 }
416}
417
418impl PartialEq for Value {
419 fn eq(&self, other: &Self) -> bool {
420 match self {
421 Value::Null => other.is_null(),
422
423 Value::Marker => other.is_marker(),
424 Value::Remove => other.is_remove(),
425 Value::Na => other.is_na(),
426
427 Value::Bool(val) => matches!(other, Value::Bool(v) if v == val),
428 Value::Number(val) => matches!(other, Value::Number(v) if v == val),
429 Value::Str(val) => matches!(other, Value::Str(v) if v == val),
430 Value::Ref(val) => matches!(other, Value::Ref(v) if v == val),
431 Value::Uri(val) => matches!(other, Value::Uri(v) if v == val),
432 Value::Symbol(val) => matches!(other, Value::Symbol(v) if v == val),
433 Value::Date(val) => matches!(other, Value::Date(v) if v == val),
434 Value::Time(val) => matches!(other, Value::Time(v) if v == val),
435 Value::DateTime(val) => matches!(other, Value::DateTime(v) if v == val),
436 Value::Coord(val) => matches!(other, Value::Coord(v) if v == val),
437 Value::XStr(val) => matches!(other, Value::XStr(v) if v == val),
438 Value::List(val) => matches!(other, Value::List(v) if v == val),
439 Value::Dict(val) => matches!(other, Value::Dict(v) if v == val),
440 Value::Grid(val) => matches!(other, Value::Grid(v) if v == val),
441 }
442 }
443}