xrust/
value.rs

1//! An atomic value.
2//!
3//! An atomic value that is an item in a sequence.
4
5use crate::qname::QualifiedName;
6use crate::xdmerror::{Error, ErrorKind};
7use chrono::{DateTime, Local, NaiveDate};
8use core::fmt;
9use core::hash::{Hash, Hasher};
10use rust_decimal::prelude::ToPrimitive;
11use rust_decimal::Decimal;
12#[cfg(test)]
13use rust_decimal_macros::dec;
14use std::cmp::Ordering;
15use std::convert::TryFrom;
16use std::fmt::Formatter;
17use std::rc::Rc;
18
19/// Comparison operators for values
20#[derive(Copy, Clone, Debug)]
21pub enum Operator {
22    Equal,
23    NotEqual,
24    LessThan,
25    LessThanEqual,
26    GreaterThan,
27    GreaterThanEqual,
28    Is,
29    Before,
30    After,
31}
32
33impl Operator {
34    pub fn to_string(&self) -> &str {
35        match self {
36            Operator::Equal => "=",
37            Operator::NotEqual => "!=",
38            Operator::LessThan => "<",
39            Operator::LessThanEqual => "<=",
40            Operator::GreaterThan => ">",
41            Operator::GreaterThanEqual => ">=",
42            Operator::Is => "is",
43            Operator::Before => "<<",
44            Operator::After => ">>",
45        }
46    }
47}
48
49impl From<String> for Operator {
50    fn from(s: String) -> Self {
51        Operator::from(s.as_str())
52    }
53}
54impl From<&str> for Operator {
55    fn from(s: &str) -> Self {
56        match s {
57            "=" | "eq" => Operator::Equal,
58            "!=" | "ne" => Operator::NotEqual,
59            "<" | "lt" => Operator::LessThan,
60            "<=" | "le" => Operator::LessThanEqual,
61            ">" | "gt" => Operator::GreaterThan,
62            ">=" | "ge" => Operator::GreaterThanEqual,
63            "is" => Operator::Is,
64            "<<" => Operator::Before,
65            ">>" => Operator::After,
66            _ => Operator::After, // TODO: add error value
67        }
68    }
69}
70
71impl fmt::Display for Operator {
72    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
73        write!(f, "{}", self.to_string())
74    }
75}
76
77/// A concrete type that implements atomic values.
78/// These are the 19 predefined types in XSD Schema Part 2, plus five additional types.
79#[derive(Clone, Debug)]
80pub enum Value {
81    /// node or simple type
82    AnyType,
83    /// a not-yet-validated anyType
84    Untyped,
85    /// base type of all simple types. i.e. not a node
86    AnySimpleType,
87    /// a list of IDREF
88    IDREFS(Vec<String>),
89    /// a list of NMTOKEN
90    NMTOKENS,
91    /// a list of ENTITY
92    ENTITIES,
93    /// Any numeric type
94    Numeric,
95    /// all atomic values (no lists or unions)
96    AnyAtomicType,
97    /// untyped atomic value
98    UntypedAtomic,
99    Duration,
100    Time(DateTime<Local>), // Ignore the date part. Perhaps use Instant instead?
101    Decimal(Decimal),
102    Float(f32),
103    Double(f64),
104    Integer(i64),
105    NonPositiveInteger(NonPositiveInteger),
106    NegativeInteger(NegativeInteger),
107    Long(i64),
108    Int(i32),
109    Short(i16),
110    Byte(i8),
111    NonNegativeInteger(NonNegativeInteger),
112    UnsignedLong(u64),
113    UnsignedInt(u32),
114    UnsignedShort(u16),
115    UnsignedByte(u8),
116    PositiveInteger(PositiveInteger),
117    DateTime(DateTime<Local>),
118    DateTimeStamp,
119    Date(NaiveDate),
120    // gYearMonth
121    // gYear
122    // gMonthDay
123    // gMonth
124    // gDay
125    String(String),
126    NormalizedString(NormalizedString),
127    /// Like normalizedString, but without leading, trailing and consecutive whitespace
128    Token,
129    /// language identifiers [a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*
130    Language,
131    /// NameChar+
132    NMTOKEN,
133    /// NameStartChar NameChar+
134    Name,
135    /// (Letter | '_') NCNameChar+ (i.e. a Name without the colon)
136    NCName,
137    /// Same format as NCName
138    ID(String),
139    /// Same format as NCName
140    IDREF(String),
141    /// Same format as NCName
142    ENTITY,
143    Boolean(bool),
144    //base64binary,
145    //hexBinary,
146    //anyURI,
147    /// Qualified Name
148    QName(QualifiedName),
149    /// Rc-shared Qualified Name
150    RQName(Rc<QualifiedName>),
151    //NOTATION
152}
153
154impl fmt::Display for Value {
155    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
156        let result = match self {
157            Value::String(s) => s.to_string(),
158            Value::NormalizedString(s) => s.0.to_string(),
159            Value::Decimal(d) => d.to_string(),
160            Value::Float(f) => f.to_string(),
161            Value::Double(d) => d.to_string(),
162            Value::Integer(i) => i.to_string(),
163            Value::Long(l) => l.to_string(),
164            Value::Short(s) => s.to_string(),
165            Value::Int(i) => i.to_string(),
166            Value::Byte(b) => b.to_string(),
167            Value::UnsignedLong(l) => l.to_string(),
168            Value::UnsignedShort(s) => s.to_string(),
169            Value::UnsignedInt(i) => i.to_string(),
170            Value::UnsignedByte(b) => b.to_string(),
171            Value::NonPositiveInteger(i) => i.0.to_string(),
172            Value::NonNegativeInteger(i) => i.0.to_string(),
173            Value::PositiveInteger(i) => i.0.to_string(),
174            Value::NegativeInteger(i) => i.0.to_string(),
175            Value::Time(t) => t.format("%H:%M:%S.%f").to_string(),
176            Value::DateTime(dt) => dt.format("%Y-%m-%dT%H:%M:%S%z").to_string(),
177            Value::Date(d) => d.format("%Y-%m-%d").to_string(),
178            Value::QName(q) => q.to_string(),
179            Value::RQName(q) => q.to_string(),
180            Value::ID(s) => s.to_string(),
181            Value::IDREF(s) => s.to_string(),
182            Value::IDREFS(s) => s.join(" ").to_string(),
183            _ => "".to_string(),
184        };
185        f.write_str(result.as_str())
186    }
187}
188
189impl Hash for Value {
190    fn hash<H: Hasher>(&self, state: &mut H) {
191        format!("{:?}", self).hash(state)
192    }
193}
194impl Eq for Value {}
195
196impl Value {
197    /// Give the effective boolean value.
198    pub fn to_bool(&self) -> bool {
199        match &self {
200            Value::Boolean(b) => *b,
201            Value::String(t) => {
202                //t.is_empty()
203                !t.is_empty()
204            }
205            Value::NormalizedString(s) => !s.0.is_empty(),
206            Value::Double(n) => *n != 0.0,
207            Value::Integer(i) => *i != 0,
208            Value::Int(i) => *i != 0,
209            _ => false,
210        }
211    }
212
213    /// Convert the value to an integer, if possible.
214    pub fn to_int(&self) -> Result<i64, Error> {
215        match &self {
216            Value::Int(i) => Ok(*i as i64),
217            Value::Integer(i) => Ok(*i),
218            _ => match self.to_string().parse::<i64>() {
219                Ok(i) => Ok(i),
220                Err(e) => Result::Err(Error::new(
221                    ErrorKind::Unknown,
222                    format!("type conversion error: {}", e),
223                )),
224            },
225        }
226    }
227    /// Convert the value to a double. If the value cannot be converted, returns Nan.
228    pub fn to_double(&self) -> f64 {
229        match &self {
230            Value::String(s) => s.parse::<f64>().unwrap_or(f64::NAN),
231            Value::Integer(i) => (*i) as f64,
232            Value::Int(i) => (*i) as f64,
233            Value::Double(d) => *d,
234            _ => f64::NAN,
235        }
236    }
237    pub fn value_type(&self) -> &'static str {
238        match &self {
239            Value::AnyType => "AnyType",
240            Value::Untyped => "Untyped",
241            Value::AnySimpleType => "AnySimpleType",
242            Value::IDREFS(_) => "IDREFS",
243            Value::NMTOKENS => "NMTOKENS",
244            Value::ENTITIES => "ENTITIES",
245            Value::Numeric => "Numeric",
246            Value::AnyAtomicType => "AnyAtomicType",
247            Value::UntypedAtomic => "UntypedAtomic",
248            Value::Duration => "Duration",
249            Value::Time(_) => "Time",
250            Value::Decimal(_) => "Decimal",
251            Value::Float(_) => "Float",
252            Value::Double(_) => "Double",
253            Value::Integer(_) => "Integer",
254            Value::NonPositiveInteger(_) => "NonPositiveInteger",
255            Value::NegativeInteger(_) => "NegativeInteger",
256            Value::Long(_) => "Long",
257            Value::Int(_) => "Int",
258            Value::Short(_) => "Short",
259            Value::Byte(_) => "Byte",
260            Value::NonNegativeInteger(_) => "NonNegativeInteger",
261            Value::UnsignedLong(_) => "UnsignedLong",
262            Value::UnsignedInt(_) => "UnsignedInt",
263            Value::UnsignedShort(_) => "UnsignedShort",
264            Value::UnsignedByte(_) => "UnsignedByte",
265            Value::PositiveInteger(_) => "PositiveInteger",
266            Value::DateTime(_) => "DateTime",
267            Value::DateTimeStamp => "DateTimeStamp",
268            Value::Date(_) => "Date",
269            Value::String(_) => "String",
270            Value::NormalizedString(_) => "NormalizedString",
271            Value::Token => "Token",
272            Value::Language => "Language",
273            Value::NMTOKEN => "NMTOKEN",
274            Value::Name => "Name",
275            Value::NCName => "NCName",
276            Value::ID(_) => "ID",
277            Value::IDREF(_) => "IDREF",
278            Value::ENTITY => "ENTITY",
279            Value::Boolean(_) => "boolean",
280            Value::QName(_) => "QName",
281            Value::RQName(_) => "QName",
282        }
283    }
284    pub fn compare(&self, other: &Value, op: Operator) -> Result<bool, Error> {
285        match &self {
286            Value::Boolean(b) => {
287                let c = other.to_bool();
288                match op {
289                    Operator::Equal => Ok(*b == c),
290                    Operator::NotEqual => Ok(*b != c),
291                    Operator::LessThan => Ok(!(*b) & c),
292                    Operator::LessThanEqual => Ok(*b <= c),
293                    Operator::GreaterThan => Ok(*b & !c),
294                    Operator::GreaterThanEqual => Ok(*b >= c),
295                    Operator::Is | Operator::Before | Operator::After => {
296                        Err(Error::new(ErrorKind::TypeError, String::from("type error")))
297                    }
298                }
299            }
300            Value::Integer(i) => {
301                let c = other.to_int()?;
302                match op {
303                    Operator::Equal => Ok(*i == c),
304                    Operator::NotEqual => Ok(*i != c),
305                    Operator::LessThan => Ok(*i < c),
306                    Operator::LessThanEqual => Ok(*i <= c),
307                    Operator::GreaterThan => Ok(*i > c),
308                    Operator::GreaterThanEqual => Ok(*i >= c),
309                    Operator::Is | Operator::Before | Operator::After => {
310                        Err(Error::new(ErrorKind::TypeError, String::from("type error")))
311                    }
312                }
313            }
314            Value::Int(i) => {
315                let c = other.to_int()? as i32;
316                match op {
317                    Operator::Equal => Ok(*i == c),
318                    Operator::NotEqual => Ok(*i != c),
319                    Operator::LessThan => Ok(*i < c),
320                    Operator::LessThanEqual => Ok(*i <= c),
321                    Operator::GreaterThan => Ok(*i > c),
322                    Operator::GreaterThanEqual => Ok(*i >= c),
323                    Operator::Is | Operator::Before | Operator::After => {
324                        Err(Error::new(ErrorKind::TypeError, String::from("type error")))
325                    }
326                }
327            }
328            Value::Double(i) => {
329                let c = other.to_double();
330                match op {
331                    Operator::Equal => Ok(*i == c),
332                    Operator::NotEqual => Ok(*i != c),
333                    Operator::LessThan => Ok(*i < c),
334                    Operator::LessThanEqual => Ok(*i <= c),
335                    Operator::GreaterThan => Ok(*i > c),
336                    Operator::GreaterThanEqual => Ok(*i >= c),
337                    Operator::Is | Operator::Before | Operator::After => {
338                        Err(Error::new(ErrorKind::TypeError, String::from("type error")))
339                    }
340                }
341            }
342            Value::String(i) => {
343                let c = other.to_string();
344                match op {
345                    Operator::Equal => Ok(*i == c),
346                    Operator::NotEqual => Ok(*i != c),
347                    Operator::LessThan => Ok(*i < c),
348                    Operator::LessThanEqual => Ok(*i <= c),
349                    Operator::GreaterThan => Ok(*i > c),
350                    Operator::GreaterThanEqual => Ok(*i >= c),
351                    Operator::Is | Operator::Before | Operator::After => {
352                        Err(Error::new(ErrorKind::TypeError, String::from("type error")))
353                    }
354                }
355            }
356            Value::QName(q) => match (op, other) {
357                (Operator::Equal, Value::QName(r)) => Ok(*q == *r),
358                (Operator::Equal, Value::RQName(r)) => Ok(*q == **r),
359                (Operator::NotEqual, Value::QName(r)) => Ok(*q != *r),
360                (Operator::NotEqual, Value::RQName(r)) => Ok(*q != **r),
361                _ => Err(Error::new(ErrorKind::TypeError, String::from("type error"))),
362            },
363            Value::RQName(q) => match (op, other) {
364                (Operator::Equal, Value::QName(r)) => Ok(**q == *r),
365                (Operator::Equal, Value::RQName(r)) => Ok(**q == **r),
366                (Operator::NotEqual, Value::QName(r)) => Ok(**q != *r),
367                (Operator::NotEqual, Value::RQName(r)) => Ok(**q != **r),
368                _ => Err(Error::new(ErrorKind::TypeError, String::from("type error"))),
369            },
370            _ => Result::Err(Error::new(
371                ErrorKind::Unknown,
372                format!(
373                    "comparing type \"{}\" is not yet implemented",
374                    self.value_type()
375                ),
376            )),
377        }
378    }
379}
380
381impl PartialEq for Value {
382    fn eq(&self, other: &Value) -> bool {
383        match self {
384            Value::String(s) => s.eq(&other.to_string()),
385            Value::Boolean(b) => match other {
386                Value::Boolean(c) => b == c,
387                _ => false, // type error?
388            },
389            Value::Decimal(d) => match other {
390                Value::Decimal(e) => d == e,
391                _ => false, // type error?
392            },
393            Value::Integer(i) => match other {
394                Value::Integer(j) => i == j,
395                _ => false, // type error? coerce to integer?
396            },
397            Value::Double(d) => match other {
398                Value::Double(e) => d == e,
399                _ => false, // type error? coerce to integer?
400            },
401            _ => false, // not yet implemented
402        }
403    }
404}
405impl PartialOrd for Value {
406    fn partial_cmp(&self, other: &Value) -> Option<Ordering> {
407        match self {
408            Value::String(s) => {
409                let o: String = other.to_string();
410                s.partial_cmp(&o)
411            }
412            Value::Boolean(_) => None,
413            Value::Decimal(d) => match other {
414                Value::Decimal(e) => d.partial_cmp(e),
415                _ => None, // type error?
416            },
417            Value::Integer(d) => match other {
418                Value::Integer(e) => d.partial_cmp(e),
419                _ => None, // type error?
420            },
421            Value::Double(d) => match other {
422                Value::Double(e) => d.partial_cmp(e),
423                _ => None, // type error?
424            },
425            _ => None,
426        }
427    }
428}
429
430//This is ONLY being used for namespace node sorting for the purposes of serializing
431//Feel free to change it.
432//We can change between versions, so long as each execution on that version is consistent.
433impl Ord for Value {
434    fn cmp(&self, other: &Value) -> Ordering {
435        match self {
436            Value::String(s) => {
437                let o: String = other.to_string();
438                s.cmp(&o)
439            }
440            Value::Boolean(_) => Ordering::Equal,
441            Value::Decimal(d) => match other {
442                Value::Decimal(e) => d.cmp(e),
443                _ => Ordering::Equal, // type error?
444            },
445            Value::Integer(d) => match other {
446                Value::Integer(e) => d.cmp(e),
447                _ => Ordering::Equal, // type error?
448            },
449            Value::Double(d) => match other {
450                Value::Double(e) => d.partial_cmp(e).unwrap_or(Ordering::Equal),
451                _ => Ordering::Equal, // type error?
452            },
453            _ => Ordering::Equal,
454        }
455    }
456}
457
458impl From<String> for Value {
459    fn from(s: String) -> Self {
460        Value::String(s)
461    }
462}
463impl From<&str> for Value {
464    fn from(s: &str) -> Self {
465        Value::String(String::from(s))
466    }
467}
468impl From<Decimal> for Value {
469    fn from(d: Decimal) -> Self {
470        Value::Decimal(d)
471    }
472}
473impl From<f32> for Value {
474    fn from(f: f32) -> Self {
475        Value::Float(f)
476    }
477}
478impl From<f64> for Value {
479    fn from(f: f64) -> Self {
480        Value::Double(f)
481    }
482}
483impl From<i64> for Value {
484    fn from(i: i64) -> Self {
485        Value::Integer(i)
486    }
487}
488impl From<i32> for Value {
489    fn from(i: i32) -> Self {
490        Value::Int(i)
491    }
492}
493impl From<i16> for Value {
494    fn from(i: i16) -> Self {
495        Value::Short(i)
496    }
497}
498impl From<i8> for Value {
499    fn from(i: i8) -> Self {
500        Value::Byte(i)
501    }
502}
503impl From<u64> for Value {
504    fn from(i: u64) -> Self {
505        Value::UnsignedLong(i)
506    }
507}
508impl From<u32> for Value {
509    fn from(i: u32) -> Self {
510        Value::UnsignedInt(i)
511    }
512}
513impl From<u16> for Value {
514    fn from(i: u16) -> Self {
515        Value::UnsignedShort(i)
516    }
517}
518impl From<u8> for Value {
519    fn from(i: u8) -> Self {
520        Value::UnsignedByte(i)
521    }
522}
523impl From<usize> for Value {
524    fn from(u: usize) -> Self {
525        Value::UnsignedLong(u.to_u64().unwrap())
526    }
527}
528impl From<bool> for Value {
529    fn from(b: bool) -> Self {
530        Value::Boolean(b)
531    }
532}
533impl From<QualifiedName> for Value {
534    fn from(q: QualifiedName) -> Self {
535        Value::QName(q)
536    }
537}
538impl From<Rc<QualifiedName>> for Value {
539    fn from(q: Rc<QualifiedName>) -> Self {
540        Value::RQName(q)
541    }
542}
543
544#[derive(Clone, Debug, Hash)]
545pub struct NonPositiveInteger(i64);
546impl TryFrom<i64> for NonPositiveInteger {
547    type Error = Error;
548    fn try_from(v: i64) -> Result<Self, Self::Error> {
549        if v > 0 {
550            Err(Error::new(
551                ErrorKind::TypeError,
552                String::from("NonPositiveInteger must be less than zero"),
553            ))
554        } else {
555            Ok(NonPositiveInteger(v))
556        }
557    }
558}
559impl fmt::Display for NonPositiveInteger {
560    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
561        f.write_str(&self.0.to_string())
562    }
563}
564
565#[derive(Clone, Debug, Hash)]
566pub struct PositiveInteger(i64);
567impl TryFrom<i64> for PositiveInteger {
568    type Error = Error;
569    fn try_from(v: i64) -> Result<Self, Self::Error> {
570        if v <= 0 {
571            Err(Error::new(
572                ErrorKind::TypeError,
573                String::from("PositiveInteger must be greater than zero"),
574            ))
575        } else {
576            Ok(PositiveInteger(v))
577        }
578    }
579}
580impl fmt::Display for PositiveInteger {
581    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
582        f.write_str(&self.0.to_string())
583    }
584}
585
586#[derive(Clone, Debug, Hash)]
587pub struct NonNegativeInteger(i64);
588impl TryFrom<i64> for NonNegativeInteger {
589    type Error = Error;
590    fn try_from(v: i64) -> Result<Self, Self::Error> {
591        if v < 0 {
592            Err(Error::new(
593                ErrorKind::TypeError,
594                String::from("NonNegativeInteger must be zero or greater"),
595            ))
596        } else {
597            Ok(NonNegativeInteger(v))
598        }
599    }
600}
601impl fmt::Display for NonNegativeInteger {
602    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
603        f.write_str(&self.0.to_string())
604    }
605}
606
607#[derive(Clone, Debug, Hash)]
608pub struct NegativeInteger(i64);
609impl TryFrom<i64> for NegativeInteger {
610    type Error = Error;
611    fn try_from(v: i64) -> Result<Self, Self::Error> {
612        if v >= 0 {
613            Err(Error::new(
614                ErrorKind::TypeError,
615                String::from("NegativeInteger must be less than zero"),
616            ))
617        } else {
618            Ok(NegativeInteger(v))
619        }
620    }
621}
622impl fmt::Display for NegativeInteger {
623    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
624        f.write_str(&self.0.to_string())
625    }
626}
627
628#[derive(Clone, Debug, Hash)]
629pub struct NormalizedString(String);
630impl TryFrom<&str> for NormalizedString {
631    type Error = Error;
632    fn try_from(v: &str) -> Result<Self, Self::Error> {
633        let n: &[_] = &['\n', '\r', '\t'];
634        if v.find(n).is_none() {
635            Ok(NormalizedString(v.to_string()))
636        } else {
637            Err(Error::new(
638                ErrorKind::TypeError,
639                String::from("value is not a normalized string"),
640            ))
641        }
642    }
643}
644impl fmt::Display for NormalizedString {
645    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
646        f.write_str(&self.0.to_string())
647    }
648}
649
650#[cfg(test)]
651mod tests {
652    use super::*;
653
654    #[test]
655    fn from_string() {
656        assert_eq!(Value::from(String::from("foobar")).to_string(), "foobar");
657    }
658    #[test]
659    fn from_str() {
660        assert_eq!(Value::from("foobar").to_string(), "foobar");
661    }
662    #[test]
663    fn from_decimal() {
664        assert_eq!(Value::from(dec!(001.23)).to_string(), "1.23");
665    }
666
667    #[test]
668    fn normalizedstring_valid_empty() {
669        assert_eq!(
670            NormalizedString::try_from("")
671                .expect("invalid NormalizedString")
672                .0,
673            ""
674        );
675    }
676    #[test]
677    fn normalizedstring_valid() {
678        assert_eq!(
679            NormalizedString::try_from("notinvalid")
680                .expect("invalid NormalizedString")
681                .0,
682            "notinvalid"
683        );
684    }
685    #[test]
686    fn normalizedstring_valid_spaces() {
687        assert_eq!(
688            NormalizedString::try_from("not an invalid string")
689                .expect("invalid NormalizedString")
690                .0,
691            "not an invalid string"
692        );
693    }
694    #[test]
695    fn normalizedstring_invalid_tab() {
696        let r = NormalizedString::try_from("contains tab	character");
697        assert!(match r {
698            Ok(_) => panic!("string contains tab character"),
699            Err(_) => true,
700        })
701    }
702    #[test]
703    fn normalizedstring_invalid_newline() {
704        let r = NormalizedString::try_from("contains newline\ncharacter");
705        assert!(match r {
706            Ok(_) => panic!("string contains newline character"),
707            Err(_) => true,
708        })
709    }
710    #[test]
711    fn normalizedstring_invalid_cr() {
712        let r = NormalizedString::try_from("contains carriage return\rcharacter");
713        assert!(match r {
714            Ok(_) => panic!("string contains cr character"),
715            Err(_) => true,
716        })
717    }
718    #[test]
719    fn normalizedstring_invalid_all() {
720        let r = NormalizedString::try_from("contains	all\rforbidden\ncharacters");
721        assert!(match r {
722            Ok(_) => panic!("string contains at least one forbidden character"),
723            Err(_) => true,
724        })
725    }
726
727    // Numeric is in the too hard basket for now
728    //    #[test]
729    //    fn numeric_float() {
730    //        assert_eq!(Numeric::new(f32::0.123).value, 0.123);
731    //    }
732    //    #[test]
733    //    fn numeric_double() {
734    //        assert_eq!(Numeric::new(f64::0.456).value, 0.456);
735    //    }
736    //    #[test]
737    //    fn numeric_decimal() {
738    //        assert_eq!(Numeric::new(dec!(123.456)), 123.456);
739    //    }
740
741    #[test]
742    fn nonpositiveinteger_valid() {
743        assert_eq!(
744            NonPositiveInteger::try_from(-10)
745                .expect("invalid NonPositiveInteger")
746                .0,
747            -10
748        );
749    }
750    #[test]
751    fn nonpositiveinteger_valid_zero() {
752        assert_eq!(
753            NonPositiveInteger::try_from(0)
754                .expect("invalid NonPositiveInteger")
755                .0,
756            0
757        );
758    }
759    #[test]
760    fn nonpositiveinteger_invalid() {
761        let r = NonPositiveInteger::try_from(10);
762        assert!(match r {
763            Ok(_) => panic!("10 is not a nonPositiveInteger"),
764            Err(_) => true,
765        })
766    }
767
768    #[test]
769    fn positiveinteger_valid() {
770        assert_eq!(
771            PositiveInteger::try_from(10)
772                .expect("invalid PositiveInteger")
773                .0,
774            10
775        );
776    }
777    #[test]
778    fn positiveinteger_invalid_zero() {
779        let r = PositiveInteger::try_from(0);
780        assert!(match r {
781            Ok(_) => panic!("0 is not a PositiveInteger"),
782            Err(_) => true,
783        })
784    }
785    #[test]
786    fn positiveinteger_invalid() {
787        let r = PositiveInteger::try_from(-10);
788        assert!(match r {
789            Ok(_) => panic!("-10 is not a PositiveInteger"),
790            Err(_) => true,
791        })
792    }
793
794    #[test]
795    fn nonnegativeinteger_valid() {
796        assert_eq!(
797            NonNegativeInteger::try_from(10)
798                .expect("invalid NonNegativeInteger")
799                .0,
800            10
801        );
802    }
803    #[test]
804    fn nonnegativeinteger_valid_zero() {
805        assert_eq!(
806            NonNegativeInteger::try_from(0)
807                .expect("invalid NonNegativeInteger")
808                .0,
809            0
810        );
811    }
812    #[test]
813    fn nonnegativeinteger_invalid() {
814        let r = NonNegativeInteger::try_from(-10);
815        assert!(match r {
816            Ok(_) => panic!("-10 is not a NonNegativeInteger"),
817            Err(_) => true,
818        })
819    }
820
821    #[test]
822    fn negativeinteger_valid() {
823        assert_eq!(
824            NegativeInteger::try_from(-10)
825                .expect("invalid NegativeInteger")
826                .0,
827            -10
828        );
829    }
830    #[test]
831    fn negativeinteger_invalid_zero() {
832        let r = NegativeInteger::try_from(0);
833        assert!(match r {
834            Ok(_) => panic!("0 is not a NegativeInteger"),
835            Err(_) => true,
836        })
837    }
838    #[test]
839    fn negativeinteger_invalid() {
840        let r = NegativeInteger::try_from(10);
841        assert!(match r {
842            Ok(_) => panic!("10 is not a NegativeInteger"),
843            Err(_) => true,
844        })
845    }
846
847    // String Values
848    #[test]
849    fn string_stringvalue() {
850        assert_eq!(Value::String("foobar".to_string()).to_string(), "foobar")
851    }
852    #[test]
853    fn decimal_stringvalue() {
854        assert_eq!(Value::Decimal(dec!(001.23)).to_string(), "1.23")
855    }
856    #[test]
857    fn float_stringvalue() {
858        assert_eq!(Value::Float(001.2300_f32).to_string(), "1.23")
859    }
860    #[test]
861    fn nonpositiveinteger_stringvalue() {
862        let npi = NonPositiveInteger::try_from(-00123).expect("invalid nonPositiveInteger");
863        let i = Value::NonPositiveInteger(npi);
864        assert_eq!(i.to_string(), "-123")
865    }
866    #[test]
867    fn nonnegativeinteger_stringvalue() {
868        let nni = NonNegativeInteger::try_from(00123).expect("invalid nonNegativeInteger");
869        let i = Value::NonNegativeInteger(nni);
870        assert_eq!(i.to_string(), "123")
871    }
872    #[test]
873    fn normalizedstring_stringvalue() {
874        let ns = NormalizedString::try_from("foobar").expect("invalid normalizedString");
875        let i = Value::NormalizedString(ns);
876        assert_eq!(i.to_string(), "foobar")
877    }
878
879    // value to_bool
880
881    #[test]
882    fn value_to_bool_string() {
883        assert!(Value::from("2").to_bool())
884    }
885
886    // value to_int
887
888    #[test]
889    fn value_to_int_string() {
890        assert_eq!(
891            Value::from("2")
892                .to_int()
893                .expect("cannot convert to integer"),
894            2
895        )
896    }
897
898    // value to_double
899
900    #[test]
901    fn value_to_double_string() {
902        assert_eq!(Value::from("3.0").to_double(), 3.0)
903    }
904
905    // value compare
906
907    #[test]
908    fn value_compare_eq() {
909        assert!(Value::from("3")
910            .compare(&Value::Double(3.0), Operator::Equal)
911            .expect("unable to compare"))
912    }
913
914    #[test]
915    fn value_compare_ne() {
916        assert!(!Value::from("3")
917            .compare(&Value::Double(3.0), Operator::NotEqual)
918            .expect("unable to compare"))
919    }
920
921    //#[test]
922    //fn value_atomize() {
923    //let i = Value::Int(123);
924    //assert_eq!(i.atomize().stringvalue(), "123")
925    //}
926
927    // Operators
928    #[test]
929    fn op_equal() {
930        assert_eq!(Operator::Equal.to_string(), "=")
931    }
932    #[test]
933    fn op_notequal() {
934        assert_eq!(Operator::NotEqual.to_string(), "!=")
935    }
936    #[test]
937    fn op_lt() {
938        assert_eq!(Operator::LessThan.to_string(), "<")
939    }
940    #[test]
941    fn op_ltequal() {
942        assert_eq!(Operator::LessThanEqual.to_string(), "<=")
943    }
944    #[test]
945    fn op_gt() {
946        assert_eq!(Operator::GreaterThan.to_string(), ">")
947    }
948    #[test]
949    fn op_gtequal() {
950        assert_eq!(Operator::GreaterThanEqual.to_string(), ">=")
951    }
952    #[test]
953    fn op_is() {
954        assert_eq!(Operator::Is.to_string(), "is")
955    }
956    #[test]
957    fn op_before() {
958        assert_eq!(Operator::Before.to_string(), "<<")
959    }
960    #[test]
961    fn op_after() {
962        assert_eq!(Operator::After.to_string(), ">>")
963    }
964}