1use chrono::{DateTime, FixedOffset};
17use minicbor::{Decode, Encode};
18use serde::{Deserialize, Serialize};
19use std::borrow::Cow;
20use std::collections::BTreeMap;
21use std::fmt;
22
23use crate::cbor::{cbor_decode_datetime, cbor_encode_datetime};
24use crate::error::StamError;
25use crate::types::*;
26use datasize::{data_size, DataSize};
27use sealed::sealed;
28use std::ops::Deref;
29
30#[sealed]
31impl TypeInfo for DataValue {
32 fn typeinfo() -> Type {
33 Type::DataValue
34 }
35}
36
37#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Encode, Decode)]
38#[serde(tag = "@type", content = "value")]
39pub enum DataValue {
42 #[n(0)]
44 Null,
45
46 #[n(1)]
48 String(#[n(0)] String),
49
50 #[n(2)]
52 Bool(#[n(0)] bool),
53
54 #[n(3)]
56 Int(#[n(0)] isize),
57
58 #[n(4)]
60 Float(#[n(0)] f64),
61
62 #[n(5)]
67 List(#[n(0)] Vec<DataValue>),
68
69 #[cbor(n(6))]
71 Datetime(
72 #[cbor(
73 n(0),
74 decode_with = "cbor_decode_datetime",
75 encode_with = "cbor_encode_datetime"
76 )]
77 DateTime<FixedOffset>,
78 ),
79
80 #[cbor(n(7))]
82 Map(#[n(0)] BTreeMap<String, DataValue>),
83}
84
85impl DataSize for DataValue {
86 const IS_DYNAMIC: bool = true;
88 const STATIC_HEAP_SIZE: usize = 8; #[inline]
91 fn estimate_heap_size(&self) -> usize {
92 match self {
93 Self::Null => 8, Self::Bool(v) => 8 + data_size(v),
95 Self::String(v) => 8 + data_size(v),
96 Self::Int(v) => 8 + data_size(v),
97 Self::Float(v) => 8 + data_size(v),
98 Self::List(v) => 8 + data_size(v),
99 Self::Map(v) => 8 + data_size(v),
100 Self::Datetime(_) => 8 + (4 * 4), }
102 }
103}
104
105#[derive(Clone, Debug, PartialEq)]
106pub enum DataOperator<'a> {
112 Null,
113 Any,
114 Equals(Cow<'a, str>),
116 EqualsInt(isize),
118 EqualsFloat(f64),
120 True,
121 False,
122 GreaterThan(isize),
124 GreaterThanOrEqual(isize),
126 GreaterThanFloat(f64),
128 GreaterThanOrEqualFloat(f64),
130 LessThan(isize),
132 LessThanOrEqual(isize),
134 LessThanFloat(f64),
136 LessThanOrEqualFloat(f64),
138 ExactDatetime(DateTime<FixedOffset>),
140 AfterDatetime(DateTime<FixedOffset>),
142 BeforeDatetime(DateTime<FixedOffset>),
144 AtOrAfterDatetime(DateTime<FixedOffset>),
146 AtOrBeforeDatetime(DateTime<FixedOffset>),
148
149 HasElement(Cow<'a, str>),
150 HasElementInt(isize),
151 HasElementFloat(f64),
152
153 GetIndex(isize, Option<Box<DataOperator<'a>>>),
155 GetKey(Cow<'a, str>, Option<Box<DataOperator<'a>>>),
157
158 Not(Box<DataOperator<'a>>),
160 And(Vec<DataOperator<'a>>),
162 Or(Vec<DataOperator<'a>>),
164}
165
166impl<'a> DataValue {
167 pub fn test(&self, operator: &DataOperator<'a>) -> bool {
170 match (self, operator) {
171 (_, DataOperator::Any) => true,
172 (Self::Null, DataOperator::Null) => true,
173 (Self::Bool(true), DataOperator::True) => true,
174 (Self::Bool(false), DataOperator::False) => true,
175 (Self::Bool(true), DataOperator::Equals(s2)) => match s2.to_lowercase().as_str() {
176 "yes" | "1" | "enable" | "enabled" | "on" | "true" => true,
177 _ => false,
178 },
179 (Self::Bool(false), DataOperator::Equals(s2)) => match s2.to_lowercase().as_str() {
180 "yes" | "1" | "enable" | "enabled" | "on" | "true" => false,
181 _ => true,
182 },
183 (Self::String(s), DataOperator::Equals(s2)) => &s.as_str() == s2,
184 (Self::Int(n), DataOperator::EqualsInt(n2)) => *n == *n2,
185 (Self::Int(n), DataOperator::GreaterThan(n2)) => *n > *n2,
186 (Self::Int(n), DataOperator::GreaterThanOrEqual(n2)) => *n >= *n2,
187 (Self::Int(n), DataOperator::LessThan(n2)) => *n < *n2,
188 (Self::Int(n), DataOperator::LessThanOrEqual(n2)) => *n <= *n2,
189 (Self::Int(n), DataOperator::Equals(s2)) => {
190 if let Ok(n2) = s2.parse::<isize>() {
191 *n == n2
192 } else {
193 false
194 }
195 }
196 (Self::Float(n), DataOperator::EqualsFloat(n2)) => *n == *n2,
197 (Self::Float(n), DataOperator::GreaterThanFloat(n2)) => *n > *n2,
198 (Self::Float(n), DataOperator::GreaterThanOrEqualFloat(n2)) => *n >= *n2,
199 (Self::Float(n), DataOperator::LessThanFloat(n2)) => *n < *n2,
200 (Self::Float(n), DataOperator::LessThanOrEqualFloat(n2)) => *n <= *n2,
201 (Self::Float(n), DataOperator::Equals(s2)) => {
202 if let Ok(n2) = s2.parse::<f64>() {
203 *n == n2
204 } else {
205 false
206 }
207 }
208 (Self::Datetime(v), DataOperator::ExactDatetime(v2)) => v == v2,
209 (Self::Datetime(v), DataOperator::AfterDatetime(v2)) => v > v2,
210 (Self::Datetime(v), DataOperator::BeforeDatetime(v2)) => v < v2,
211 (Self::Datetime(v), DataOperator::AtOrAfterDatetime(v2)) => v >= v2,
212 (Self::Datetime(v), DataOperator::AtOrBeforeDatetime(v2)) => v <= v2,
213 (Self::Datetime(v), DataOperator::Equals(s2)) => {
214 if let Ok(v2) = DateTime::parse_from_rfc3339(s2) {
215 *v == v2
216 } else {
217 false
218 }
219 }
220 (Self::List(v), DataOperator::HasElement(s)) => {
221 v.iter().any(|e| e.test(&DataOperator::Equals(s.clone())))
222 }
223 (Self::List(v), DataOperator::HasElementInt(n)) => {
224 v.iter().any(|e| e.test(&DataOperator::EqualsInt(*n)))
225 }
226 (Self::List(v), DataOperator::HasElementFloat(f)) => {
227 v.iter().any(|e| e.test(&DataOperator::EqualsFloat(*f)))
228 }
229 (Self::Map(v), DataOperator::HasElement(s)) => v.contains_key(s.as_ref()),
230 (Self::Map(v), DataOperator::GetKey(s, Some(op))) => {
231 v.get(s.as_ref()).map(|e| e.test(&op)).unwrap_or(false)
232 }
233 (Self::Map(v), DataOperator::GetKey(s, None)) => v.contains_key(s.as_ref()),
234 (Self::List(v), DataOperator::GetIndex(i, Some(op))) => v
235 .iter()
236 .nth(*i as usize)
237 .map(|e| e.test(&op))
238 .unwrap_or(false),
239 (Self::List(v), DataOperator::GetIndex(i, None)) => v.len() > *i as usize,
240 (value, DataOperator::Not(operator)) => !value.test(operator),
241 (value, DataOperator::And(operators)) => {
242 operators.iter().all(|operator| value.test(operator))
243 }
244 (value, DataOperator::Or(operators)) => {
245 operators.iter().any(|operator| value.test(operator))
246 }
247 _ => false,
248 }
249 }
250
251 pub fn to_json(&self) -> Result<String, StamError> {
253 serde_json::to_string_pretty(&self).map_err(|e| {
255 StamError::SerializationError(format!("Writing datavalue to string: {}", e))
256 })
257 }
258
259 pub fn to_json_compact(&self) -> Result<String, StamError> {
261 serde_json::to_string(&self).map_err(|e| {
263 StamError::SerializationError(format!("Writing datavalue to string: {}", e))
264 })
265 }
266}
267
268impl fmt::Display for DataValue {
269 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
270 match self {
271 Self::Null => write!(f, "null"),
272 Self::String(v) => write!(f, "{}", v),
273 Self::Bool(v) => write!(f, "{}", v),
274 Self::Int(v) => write!(f, "{}", v),
275 Self::Float(v) => write!(f, "{}", v),
276 Self::Datetime(v) => write!(f, "{}", v.to_rfc3339()),
277 Self::List(v) => {
278 for (i, item) in v.iter().enumerate() {
279 if i < v.len() - 1 {
280 write!(f, ", ")?;
281 }
282 write!(f, "{}", item)?;
283 }
284 Ok(())
285 }
286 Self::Map(v) => {
287 for (i, (key, item)) in v.iter().enumerate() {
288 if i < v.len() - 1 {
289 write!(f, ", ")?;
290 }
291 write!(f, "{}: {}", key, item)?;
292 }
293 Ok(())
294 }
295 }
296 }
297}
298
299impl From<&str> for DataValue {
300 fn from(item: &str) -> Self {
301 Self::String(item.to_string())
302 }
303}
304
305impl From<String> for DataValue {
306 fn from(item: String) -> Self {
307 Self::String(item)
308 }
309}
310
311impl From<f64> for DataValue {
312 fn from(item: f64) -> Self {
313 Self::Float(item)
314 }
315}
316
317impl From<f32> for DataValue {
318 fn from(item: f32) -> Self {
319 Self::Float(item as f64)
320 }
321}
322
323impl From<isize> for DataValue {
324 fn from(item: isize) -> Self {
325 Self::Int(item)
326 }
327}
328
329impl From<i64> for DataValue {
330 fn from(item: i64) -> Self {
331 Self::Int(item as isize)
332 }
333}
334
335impl From<i32> for DataValue {
336 fn from(item: i32) -> Self {
337 Self::Int(item as isize)
338 }
339}
340
341impl From<i16> for DataValue {
342 fn from(item: i16) -> Self {
343 Self::Int(item as isize)
344 }
345}
346
347impl From<i8> for DataValue {
348 fn from(item: i8) -> Self {
349 Self::Int(item as isize)
350 }
351}
352
353impl From<usize> for DataValue {
354 fn from(item: usize) -> Self {
355 Self::Int(
356 item.try_into()
357 .expect("integer out of bounds (u64 -> i64 failed)"),
358 )
359 }
360}
361
362impl From<u64> for DataValue {
363 fn from(item: u64) -> Self {
364 Self::Int(
365 item.try_into()
366 .expect("integer out of bounds (u64 -> i64 failed)"),
367 )
368 }
369}
370
371impl From<u32> for DataValue {
372 fn from(item: u32) -> Self {
373 Self::Int(item.try_into().unwrap())
374 }
375}
376
377impl From<u16> for DataValue {
378 fn from(item: u16) -> Self {
379 Self::Int(item.try_into().unwrap())
380 }
381}
382
383impl From<u8> for DataValue {
384 fn from(item: u8) -> Self {
385 Self::Int(item.try_into().unwrap())
386 }
387}
388
389impl From<bool> for DataValue {
390 fn from(item: bool) -> Self {
391 Self::Bool(item)
392 }
393}
394
395impl From<Vec<DataValue>> for DataValue {
396 fn from(item: Vec<DataValue>) -> Self {
397 Self::List(item)
398 }
399}
400
401impl From<BTreeMap<String, DataValue>> for DataValue {
402 fn from(item: BTreeMap<String, DataValue>) -> Self {
403 Self::Map(item)
404 }
405}
406
407impl From<Vec<(String, DataValue)>> for DataValue {
408 fn from(item: Vec<(String, DataValue)>) -> Self {
409 let mut map = BTreeMap::new();
410 for (k, v) in item {
411 map.insert(k, v);
412 }
413 Self::Map(map)
414 }
415}
416
417impl From<DateTime<FixedOffset>> for DataValue {
418 fn from(item: DateTime<FixedOffset>) -> Self {
419 Self::Datetime(item)
420 }
421}
422
423impl PartialEq<str> for DataValue {
426 fn eq(&self, other: &str) -> bool {
427 match self {
428 Self::String(v) => v == other,
429 _ => false,
430 }
431 }
432}
433
434impl PartialEq<&str> for DataValue {
435 fn eq(&self, other: &&str) -> bool {
436 match self {
437 Self::String(v) => v == other,
438 _ => false,
439 }
440 }
441}
442
443impl PartialEq<DataValue> for str {
444 fn eq(&self, other: &DataValue) -> bool {
445 match other {
446 DataValue::String(v) => v.as_str() == self,
447 _ => false,
448 }
449 }
450}
451
452impl PartialEq<DataValue> for &str {
453 fn eq(&self, other: &DataValue) -> bool {
454 match other {
455 DataValue::String(v) => v.as_str() == *self,
456 _ => false,
457 }
458 }
459}
460
461impl PartialEq<f64> for DataValue {
462 fn eq(&self, other: &f64) -> bool {
463 match self {
464 Self::Float(v) => v == other,
465 _ => false,
466 }
467 }
468}
469
470impl PartialEq<DataValue> for f64 {
471 fn eq(&self, other: &DataValue) -> bool {
472 match other {
473 DataValue::Float(v) => v == self,
474 _ => false,
475 }
476 }
477}
478
479impl PartialEq<isize> for DataValue {
480 fn eq(&self, other: &isize) -> bool {
481 match self {
482 Self::Int(v) => v == other,
483 _ => false,
484 }
485 }
486}
487
488impl PartialEq<DataValue> for isize {
489 fn eq(&self, other: &DataValue) -> bool {
490 match other {
491 DataValue::Int(v) => v == self,
492 _ => false,
493 }
494 }
495}
496
497impl PartialEq<DataValue> for BTreeMap<String, DataValue> {
498 fn eq(&self, other: &DataValue) -> bool {
499 match other {
500 DataValue::Map(v) => v == self,
501 _ => false,
502 }
503 }
504}
505
506impl PartialEq<DataValue> for DateTime<FixedOffset> {
507 fn eq(&self, other: &DataValue) -> bool {
508 match other {
509 DataValue::Datetime(v) => v == self,
510 _ => false,
511 }
512 }
513}
514
515impl<'a> TryFrom<DataOperator<'a>> for DataValue {
516 type Error = StamError;
517
518 fn try_from(operator: DataOperator<'a>) -> Result<Self, Self::Error> {
519 match operator {
520 DataOperator::Null => Ok(Self::Null),
521 DataOperator::Equals(s) => Ok(Self::String(s.to_string())),
522 DataOperator::EqualsFloat(f) => Ok(Self::Float(f)),
523 DataOperator::EqualsInt(i) => Ok(Self::Int(i)),
524 DataOperator::True => Ok(Self::Bool(true)),
525 DataOperator::False => Ok(Self::Bool(false)),
526 DataOperator::ExactDatetime(v) => Ok(Self::Datetime(v)),
527 _ => Err(StamError::OtherError(
528 "Data operator can not be converted to a single DataValue",
529 )),
530 }
531 }
532}
533
534impl<'a> From<&'a DataValue> for DataOperator<'a> {
535 fn from(v: &'a DataValue) -> Self {
536 match v {
537 DataValue::Null => DataOperator::Null,
538 DataValue::String(s) => DataOperator::Equals(s.as_str().into()),
539 DataValue::Int(v) => DataOperator::EqualsInt(*v),
540 DataValue::Float(v) => DataOperator::EqualsFloat(*v),
541 DataValue::Bool(true) => DataOperator::True,
542 DataValue::Bool(false) => DataOperator::False,
543 DataValue::Datetime(v) => DataOperator::ExactDatetime(*v),
544 DataValue::List(_) => {
545 eprintln!("STAM warning: Automatic conversion from list values to operators is not supported!");
546 DataOperator::Null
547 }
548 DataValue::Map(_) => {
549 eprintln!("STAM warning: Automatic conversion from map values to operators is not supported!");
550 DataOperator::Null
551 }
552 }
553 }
554}
555
556impl<'a> From<&'a str> for DataOperator<'a> {
557 fn from(s: &'a str) -> Self {
558 DataOperator::Equals(s.into())
559 }
560}
561
562impl<'a> From<isize> for DataOperator<'a> {
563 fn from(v: isize) -> Self {
564 DataOperator::EqualsInt(v)
565 }
566}
567
568impl<'a> From<usize> for DataOperator<'a> {
569 fn from(v: usize) -> Self {
570 DataOperator::EqualsInt(v as isize)
571 }
572}
573
574impl<'a> From<f64> for DataOperator<'a> {
575 fn from(v: f64) -> Self {
576 DataOperator::EqualsFloat(v)
577 }
578}
579
580impl<'a> From<DateTime<FixedOffset>> for DataOperator<'a> {
581 fn from(v: DateTime<FixedOffset>) -> Self {
582 DataOperator::ExactDatetime(v)
583 }
584}
585
586impl<'a> From<bool> for DataOperator<'a> {
587 fn from(v: bool) -> Self {
588 if v {
589 DataOperator::True
590 } else {
591 DataOperator::False
592 }
593 }
594}
595
596impl<'a> DataOperator<'a> {
597 pub fn to_string(&self) -> Result<String, StamError> {
599 match self {
600 DataOperator::Any => Ok(format!("= any")),
601 DataOperator::Null => Ok(format!("= null")),
602 DataOperator::True => Ok(format!("= true")),
603 DataOperator::False => Ok(format!("= false")),
604 DataOperator::Equals(s) => Ok(format!("= \"{}\"", s)),
605 DataOperator::Not(expr) => match expr.deref() {
606 DataOperator::Equals(..)
607 | DataOperator::EqualsInt(..)
608 | DataOperator::EqualsFloat(..)
609 | DataOperator::Any
610 | DataOperator::Null
611 | DataOperator::True
612 | DataOperator::False => Ok(format!("!{}", expr.to_string()?)),
613 _ => Err(StamError::QuerySyntaxError(
614 format!(
615 "There is no query syntax yet for this dataoperator expression: {:?}",
616 self
617 ),
618 "DataOperator::to_string()",
619 )),
620 },
621 DataOperator::EqualsInt(n) => Ok(format!("= {}", n)),
622 DataOperator::EqualsFloat(n) => Ok(format!("= {}", n)),
623 DataOperator::GreaterThan(n) => Ok(format!("> {}", n)),
624 DataOperator::GreaterThanOrEqual(n) => Ok(format!(">= {}", n)),
625 DataOperator::LessThan(n) => Ok(format!("< {}", n)),
626 DataOperator::LessThanOrEqual(n) => Ok(format!("<= {}", n)),
627 DataOperator::GreaterThanFloat(n) => Ok(format!("> {}", n)),
628 DataOperator::GreaterThanOrEqualFloat(n) => Ok(format!(">= {}", n)),
629 DataOperator::LessThanOrEqualFloat(n) => Ok(format!("<= {}", n)),
630 DataOperator::LessThanFloat(n) => Ok(format!("< {}", n)),
631 DataOperator::ExactDatetime(d) => Ok(format!("= {}", d.to_rfc3339())),
632 DataOperator::AfterDatetime(d) => Ok(format!("> {}", d.to_rfc3339())),
633 DataOperator::AtOrAfterDatetime(d) => Ok(format!(">= {}", d.to_rfc3339())),
634 DataOperator::BeforeDatetime(d) => Ok(format!("< {}", d.to_rfc3339())),
635 DataOperator::AtOrBeforeDatetime(d) => Ok(format!("<= {}", d.to_rfc3339())),
636 DataOperator::HasElement(s) => Ok(format!("HAS {}", s)),
637 DataOperator::HasElementInt(n) => Ok(format!("HAS {}", n)),
638 DataOperator::HasElementFloat(n) => Ok(format!("HAS {}", n)),
639 DataOperator::GetKey(s, None) => Ok(format!(". {}", s)),
640 DataOperator::GetIndex(n, None) => Ok(format!(". {}", n)),
641 DataOperator::GetKey(s, Some(op)) => Ok(format!(". {} {}", s, &op.to_string()?)),
642 DataOperator::GetIndex(n, Some(op)) => Ok(format!(". {} {}", n, &op.to_string()?)),
643 _ => {
644 Err(StamError::QuerySyntaxError(
646 format!(
647 "There is no query syntax yet for this dataoperator expression: {:?}",
648 self
649 ),
650 "DataOperator::to_string()",
651 ))
652 }
653 }
654 }
655}