1use 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#[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, }
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#[derive(Clone, Debug)]
80pub enum Value {
81 AnyType,
83 Untyped,
85 AnySimpleType,
87 IDREFS(Vec<String>),
89 NMTOKENS,
91 ENTITIES,
93 Numeric,
95 AnyAtomicType,
97 UntypedAtomic,
99 Duration,
100 Time(DateTime<Local>), 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 String(String),
126 NormalizedString(NormalizedString),
127 Token,
129 Language,
131 NMTOKEN,
133 Name,
135 NCName,
137 ID(String),
139 IDREF(String),
141 ENTITY,
143 Boolean(bool),
144 QName(QualifiedName),
149 RQName(Rc<QualifiedName>),
151 }
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 pub fn to_bool(&self) -> bool {
199 match &self {
200 Value::Boolean(b) => *b,
201 Value::String(t) => {
202 !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 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 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, },
389 Value::Decimal(d) => match other {
390 Value::Decimal(e) => d == e,
391 _ => false, },
393 Value::Integer(i) => match other {
394 Value::Integer(j) => i == j,
395 _ => false, },
397 Value::Double(d) => match other {
398 Value::Double(e) => d == e,
399 _ => false, },
401 _ => false, }
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, },
417 Value::Integer(d) => match other {
418 Value::Integer(e) => d.partial_cmp(e),
419 _ => None, },
421 Value::Double(d) => match other {
422 Value::Double(e) => d.partial_cmp(e),
423 _ => None, },
425 _ => None,
426 }
427 }
428}
429
430impl 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, },
445 Value::Integer(d) => match other {
446 Value::Integer(e) => d.cmp(e),
447 _ => Ordering::Equal, },
449 Value::Double(d) => match other {
450 Value::Double(e) => d.partial_cmp(e).unwrap_or(Ordering::Equal),
451 _ => Ordering::Equal, },
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 #[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 #[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 #[test]
882 fn value_to_bool_string() {
883 assert!(Value::from("2").to_bool())
884 }
885
886 #[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 #[test]
901 fn value_to_double_string() {
902 assert_eq!(Value::from("3.0").to_double(), 3.0)
903 }
904
905 #[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]
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}