xrust/
value.rs

1//! An atomic value.
2//!
3//! An atomic value that is an item in a sequence.
4
5use crate::output::OutputSpec;
6use crate::qname::QualifiedName;
7use crate::xdmerror::{Error, ErrorKind};
8use chrono::{DateTime, Local, NaiveDate};
9use core::fmt;
10use core::hash::{Hash, Hasher};
11use rust_decimal::Decimal;
12use rust_decimal::prelude::ToPrimitive;
13#[cfg(test)]
14use rust_decimal_macros::dec;
15use std::cmp::Ordering;
16use std::convert::TryFrom;
17use std::fmt::Formatter;
18use std::rc::Rc;
19
20/// Comparison operators for values
21#[derive(Copy, Clone, Debug)]
22pub enum Operator {
23    Equal,
24    NotEqual,
25    LessThan,
26    LessThanEqual,
27    GreaterThan,
28    GreaterThanEqual,
29    Is,
30    Before,
31    After,
32}
33
34impl Operator {
35    pub fn to_string(&self) -> &str {
36        match self {
37            Operator::Equal => "=",
38            Operator::NotEqual => "!=",
39            Operator::LessThan => "<",
40            Operator::LessThanEqual => "<=",
41            Operator::GreaterThan => ">",
42            Operator::GreaterThanEqual => ">=",
43            Operator::Is => "is",
44            Operator::Before => "<<",
45            Operator::After => ">>",
46        }
47    }
48}
49
50impl From<String> for Operator {
51    fn from(s: String) -> Self {
52        Operator::from(s.as_str())
53    }
54}
55impl From<&str> for Operator {
56    fn from(s: &str) -> Self {
57        match s {
58            "=" | "eq" => Operator::Equal,
59            "!=" | "ne" => Operator::NotEqual,
60            "<" | "lt" => Operator::LessThan,
61            "<=" | "le" => Operator::LessThanEqual,
62            ">" | "gt" => Operator::GreaterThan,
63            ">=" | "ge" => Operator::GreaterThanEqual,
64            "is" => Operator::Is,
65            "<<" => Operator::Before,
66            ">>" => Operator::After,
67            _ => Operator::After, // TODO: add error value
68        }
69    }
70}
71
72impl fmt::Display for Operator {
73    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
74        write!(f, "{}", self.to_string())
75    }
76}
77
78/// A concrete type that implements atomic values.
79/// These are the 19 predefined types in XSD Schema Part 2, plus five additional types.
80/// Also included is a hint for serialisation for if the value should be escaped.
81#[derive(Clone, Debug)]
82pub struct Value {
83    pub value: ValueData,
84    pub output: OutputSpec,
85}
86
87impl Value {
88    pub fn value_ref(&self) -> &ValueData {
89        &self.value
90    }
91    pub fn output_ref(&self) -> &OutputSpec {
92        &self.output
93    }
94}
95
96pub struct ValueBuilder {
97    value: Option<ValueData>,
98    output: OutputSpec,
99}
100
101impl ValueBuilder {
102    pub fn new() -> Self {
103        ValueBuilder {
104            value: None,
105            output: OutputSpec::Normal,
106        }
107    }
108    pub fn value(mut self, v: ValueData) -> Self {
109        self.value = Some(v);
110        self
111    }
112    pub fn output(mut self, o: OutputSpec) -> Self {
113        self.output = o;
114        self
115    }
116    /// Produce the Value. This will panic if a value has not been specified.
117    pub fn build(self) -> Value {
118        Value {
119            value: self.value.unwrap(),
120            output: self.output,
121        }
122    }
123}
124/// Derive a new [ValueBuilder] from an existing [Value]. The value data in the old Value will be copie to the builder.
125impl From<&Value> for ValueBuilder {
126    fn from(v: &Value) -> Self {
127        ValueBuilder {
128            value: Some(v.value.clone()),
129            output: OutputSpec::Normal,
130        }
131    }
132}
133
134#[derive(Clone, Debug)]
135pub enum ValueData {
136    /// node or simple type
137    AnyType,
138    /// a not-yet-validated anyType
139    Untyped,
140    /// base type of all simple types. i.e. not a node
141    AnySimpleType,
142    /// a list of IDREF
143    IDREFS(Vec<IDREF>),
144    /// a list of NMTOKEN
145    NMTOKENS(Vec<NMTOKEN>),
146    /// a list of ENTITY
147    ENTITIES(Vec<ENTITY>),
148    /// Any numeric type
149    Numeric,
150    /// all atomic values (no lists or unions)
151    AnyAtomicType,
152    /// untyped atomic value
153    UntypedAtomic,
154    Duration,
155    Time(DateTime<Local>), // Ignore the date part. Perhaps use Instant instead?
156    Decimal(Decimal),
157    Float(f32),
158    Double(f64),
159    Integer(i64),
160    NonPositiveInteger(NonPositiveInteger),
161    NegativeInteger(NegativeInteger),
162    Long(i64),
163    Int(i32),
164    Short(i16),
165    Byte(i8),
166    NonNegativeInteger(NonNegativeInteger),
167    UnsignedLong(u64),
168    UnsignedInt(u32),
169    UnsignedShort(u16),
170    UnsignedByte(u8),
171    PositiveInteger(PositiveInteger),
172    DateTime(DateTime<Local>),
173    DateTimeStamp,
174    Date(NaiveDate),
175    // gYearMonth
176    // gYear
177    // gMonthDay
178    // gMonth
179    // gDay
180    String(String),
181    NormalizedString(NormalizedString),
182    /// Like normalizedString, but without leading, trailing and consecutive whitespace
183    Token,
184    /// language identifiers [a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*
185    Language,
186    /// NameChar+
187    NMTOKEN(NMTOKEN),
188    /// NameStartChar NameChar+
189    Name(Name),
190    /// (Letter | '_') NCNameChar+ (i.e. a Name without the colon)
191    NCName(NCName),
192    /// Same format as NCName
193    ID(ID),
194    /// Same format as NCName
195    IDREF(IDREF),
196    /// Same format as NCName
197    ENTITY(ENTITY),
198    Boolean(bool),
199    //base64binary,
200    //hexBinary,
201    //anyURI,
202    /// Qualified Name
203    QName(QualifiedName),
204    /// Rc-shared Qualified Name
205    RQName(Rc<QualifiedName>),
206    //NOTATION
207}
208
209impl fmt::Display for Value {
210    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
211        let result = match &self.value {
212            ValueData::String(s) => s.to_string(),
213            ValueData::NormalizedString(s) => s.0.to_string(),
214            ValueData::Decimal(d) => d.to_string(),
215            ValueData::Float(f) => f.to_string(),
216            ValueData::Double(d) => d.to_string(),
217            ValueData::Integer(i) => i.to_string(),
218            ValueData::Long(l) => l.to_string(),
219            ValueData::Short(s) => s.to_string(),
220            ValueData::Int(i) => i.to_string(),
221            ValueData::Byte(b) => b.to_string(),
222            ValueData::UnsignedLong(l) => l.to_string(),
223            ValueData::UnsignedShort(s) => s.to_string(),
224            ValueData::UnsignedInt(i) => i.to_string(),
225            ValueData::UnsignedByte(b) => b.to_string(),
226            ValueData::NonPositiveInteger(i) => i.0.to_string(),
227            ValueData::NonNegativeInteger(i) => i.0.to_string(),
228            ValueData::PositiveInteger(i) => i.0.to_string(),
229            ValueData::NegativeInteger(i) => i.0.to_string(),
230            ValueData::Time(t) => t.format("%H:%M:%S.%f").to_string(),
231            ValueData::DateTime(dt) => dt.format("%Y-%m-%dT%H:%M:%S%z").to_string(),
232            ValueData::Date(d) => d.format("%Y-%m-%d").to_string(),
233            ValueData::QName(q) => q.to_string(),
234            ValueData::RQName(q) => q.to_string(),
235            ValueData::ID(s) => s.to_string(),
236            ValueData::IDREF(s) => s.to_string(),
237            // TODO: use .intersperse() when it is available
238            ValueData::IDREFS(v) => {
239                let mut result = v
240                    .iter()
241                    .fold(String::new(), |s, i| s + i.to_string().as_str() + " ");
242                result.pop();
243                result
244            }
245            _ => "".to_string(),
246        };
247        f.write_str(result.as_str())
248    }
249}
250
251impl Hash for Value {
252    fn hash<H: Hasher>(&self, state: &mut H) {
253        format!("{:?}", self.value).hash(state)
254    }
255}
256impl Eq for Value {}
257
258impl Value {
259    /// Create a Time, ignoring the date part
260    pub fn new_time(t: DateTime<Local>) -> Self {
261        Value {
262            value: ValueData::Time(t),
263            output: OutputSpec::Normal,
264        }
265    }
266    /// Create a date
267    pub fn new_date(d: NaiveDate) -> Self {
268        Value {
269            value: ValueData::Date(d),
270            output: OutputSpec::Normal,
271        }
272    }
273    /// Give the effective boolean value.
274    pub fn to_bool(&self) -> bool {
275        match &self.value {
276            ValueData::Boolean(b) => *b,
277            ValueData::String(t) => {
278                //t.is_empty()
279                !t.is_empty()
280            }
281            ValueData::NormalizedString(s) => !s.0.is_empty(),
282            ValueData::Double(n) => *n != 0.0,
283            ValueData::Integer(i) => *i != 0,
284            ValueData::Int(i) => *i != 0,
285            _ => false,
286        }
287    }
288
289    /// Convert the value to an integer, if possible.
290    pub fn to_int(&self) -> Result<i64, Error> {
291        match &self.value {
292            ValueData::Int(i) => Ok(*i as i64),
293            ValueData::Integer(i) => Ok(*i),
294            _ => match self.to_string().parse::<i64>() {
295                Ok(i) => Ok(i),
296                Err(e) => Result::Err(Error::new(
297                    ErrorKind::Unknown,
298                    format!("type conversion error: {}", e),
299                )),
300            },
301        }
302    }
303    /// Convert the value to a double. If the value cannot be converted, returns Nan.
304    pub fn to_double(&self) -> f64 {
305        match &self.value {
306            ValueData::String(s) => s.parse::<f64>().unwrap_or(f64::NAN),
307            ValueData::Integer(i) => (*i) as f64,
308            ValueData::Int(i) => (*i) as f64,
309            ValueData::Double(d) => *d,
310            _ => f64::NAN,
311        }
312    }
313    pub fn value_type(&self) -> &'static str {
314        match &self.value {
315            ValueData::AnyType => "AnyType",
316            ValueData::Untyped => "Untyped",
317            ValueData::AnySimpleType => "AnySimpleType",
318            ValueData::IDREFS(_) => "IDREFS",
319            ValueData::NMTOKENS(_) => "NMTOKENS",
320            ValueData::ENTITIES(_) => "ENTITIES",
321            ValueData::Numeric => "Numeric",
322            ValueData::AnyAtomicType => "AnyAtomicType",
323            ValueData::UntypedAtomic => "UntypedAtomic",
324            ValueData::Duration => "Duration",
325            ValueData::Time(_) => "Time",
326            ValueData::Decimal(_) => "Decimal",
327            ValueData::Float(_) => "Float",
328            ValueData::Double(_) => "Double",
329            ValueData::Integer(_) => "Integer",
330            ValueData::NonPositiveInteger(_) => "NonPositiveInteger",
331            ValueData::NegativeInteger(_) => "NegativeInteger",
332            ValueData::Long(_) => "Long",
333            ValueData::Int(_) => "Int",
334            ValueData::Short(_) => "Short",
335            ValueData::Byte(_) => "Byte",
336            ValueData::NonNegativeInteger(_) => "NonNegativeInteger",
337            ValueData::UnsignedLong(_) => "UnsignedLong",
338            ValueData::UnsignedInt(_) => "UnsignedInt",
339            ValueData::UnsignedShort(_) => "UnsignedShort",
340            ValueData::UnsignedByte(_) => "UnsignedByte",
341            ValueData::PositiveInteger(_) => "PositiveInteger",
342            ValueData::DateTime(_) => "DateTime",
343            ValueData::DateTimeStamp => "DateTimeStamp",
344            ValueData::Date(_) => "Date",
345            ValueData::String(_) => "String",
346            ValueData::NormalizedString(_) => "NormalizedString",
347            ValueData::Token => "Token",
348            ValueData::Language => "Language",
349            ValueData::NMTOKEN(_) => "NMTOKEN",
350            ValueData::Name(_) => "Name",
351            ValueData::NCName(_) => "NCName",
352            ValueData::ID(_) => "ID",
353            ValueData::IDREF(_) => "IDREF",
354            ValueData::ENTITY(_) => "ENTITY",
355            ValueData::Boolean(_) => "boolean",
356            ValueData::QName(_) => "QName",
357            ValueData::RQName(_) => "QName",
358        }
359    }
360    pub fn compare(&self, other: &Value, op: Operator) -> Result<bool, Error> {
361        match &self.value {
362            ValueData::Boolean(b) => {
363                let c = other.to_bool();
364                match op {
365                    Operator::Equal => Ok(*b == c),
366                    Operator::NotEqual => Ok(*b != c),
367                    Operator::LessThan => Ok(!(*b) & c),
368                    Operator::LessThanEqual => Ok(*b <= c),
369                    Operator::GreaterThan => Ok(*b & !c),
370                    Operator::GreaterThanEqual => Ok(*b >= c),
371                    Operator::Is | Operator::Before | Operator::After => {
372                        Err(Error::new(ErrorKind::TypeError, String::from("type error")))
373                    }
374                }
375            }
376            ValueData::Integer(i) => {
377                let c = other.to_int()?;
378                match op {
379                    Operator::Equal => Ok(*i == c),
380                    Operator::NotEqual => Ok(*i != c),
381                    Operator::LessThan => Ok(*i < c),
382                    Operator::LessThanEqual => Ok(*i <= c),
383                    Operator::GreaterThan => Ok(*i > c),
384                    Operator::GreaterThanEqual => Ok(*i >= c),
385                    Operator::Is | Operator::Before | Operator::After => {
386                        Err(Error::new(ErrorKind::TypeError, String::from("type error")))
387                    }
388                }
389            }
390            ValueData::Int(i) => {
391                let c = other.to_int()? as i32;
392                match op {
393                    Operator::Equal => Ok(*i == c),
394                    Operator::NotEqual => Ok(*i != c),
395                    Operator::LessThan => Ok(*i < c),
396                    Operator::LessThanEqual => Ok(*i <= c),
397                    Operator::GreaterThan => Ok(*i > c),
398                    Operator::GreaterThanEqual => Ok(*i >= c),
399                    Operator::Is | Operator::Before | Operator::After => {
400                        Err(Error::new(ErrorKind::TypeError, String::from("type error")))
401                    }
402                }
403            }
404            ValueData::Double(i) => {
405                let c = other.to_double();
406                match op {
407                    Operator::Equal => Ok(*i == c),
408                    Operator::NotEqual => Ok(*i != c),
409                    Operator::LessThan => Ok(*i < c),
410                    Operator::LessThanEqual => Ok(*i <= c),
411                    Operator::GreaterThan => Ok(*i > c),
412                    Operator::GreaterThanEqual => Ok(*i >= c),
413                    Operator::Is | Operator::Before | Operator::After => {
414                        Err(Error::new(ErrorKind::TypeError, String::from("type error")))
415                    }
416                }
417            }
418            ValueData::String(i) => {
419                let c = other.to_string();
420                match op {
421                    Operator::Equal => Ok(*i == c),
422                    Operator::NotEqual => Ok(*i != c),
423                    Operator::LessThan => Ok(*i < c),
424                    Operator::LessThanEqual => Ok(*i <= c),
425                    Operator::GreaterThan => Ok(*i > c),
426                    Operator::GreaterThanEqual => Ok(*i >= c),
427                    Operator::Is | Operator::Before | Operator::After => {
428                        Err(Error::new(ErrorKind::TypeError, String::from("type error")))
429                    }
430                }
431            }
432            ValueData::QName(q) => match (op, &other.value) {
433                (Operator::Equal, ValueData::QName(r)) => Ok(*q == *r),
434                (Operator::Equal, ValueData::RQName(r)) => Ok(*q == **r),
435                (Operator::NotEqual, ValueData::QName(r)) => Ok(*q != *r),
436                (Operator::NotEqual, ValueData::RQName(r)) => Ok(*q != **r),
437                _ => Err(Error::new(ErrorKind::TypeError, String::from("type error"))),
438            },
439            ValueData::RQName(q) => match (op, &other.value) {
440                (Operator::Equal, ValueData::QName(r)) => Ok(**q == *r),
441                (Operator::Equal, ValueData::RQName(r)) => Ok(**q == **r),
442                (Operator::NotEqual, ValueData::QName(r)) => Ok(**q != *r),
443                (Operator::NotEqual, ValueData::RQName(r)) => Ok(**q != **r),
444                _ => Err(Error::new(ErrorKind::TypeError, String::from("type error"))),
445            },
446            _ => Result::Err(Error::new(
447                ErrorKind::Unknown,
448                format!(
449                    "comparing type \"{}\" is not yet implemented",
450                    self.value_type()
451                ),
452            )),
453        }
454    }
455}
456
457impl PartialEq for Value {
458    fn eq(&self, other: &Value) -> bool {
459        match &self.value {
460            ValueData::String(s) => s.eq(&other.to_string()),
461            ValueData::Boolean(b) => match other.value {
462                ValueData::Boolean(c) => *b == c,
463                _ => false, // type error?
464            },
465            ValueData::Decimal(d) => match other.value {
466                ValueData::Decimal(e) => *d == e,
467                _ => false, // type error?
468            },
469            ValueData::Integer(i) => match other.value {
470                ValueData::Integer(j) => *i == j,
471                _ => false, // type error? coerce to integer?
472            },
473            ValueData::Double(d) => match other.value {
474                ValueData::Double(e) => *d == e,
475                _ => false, // type error? coerce to integer?
476            },
477            _ => false, // not yet implemented
478        }
479    }
480}
481impl PartialOrd for Value {
482    fn partial_cmp(&self, other: &Value) -> Option<Ordering> {
483        match &self.value {
484            ValueData::String(s) => {
485                let o: String = other.to_string();
486                s.partial_cmp(&o)
487            }
488            ValueData::Boolean(_) => None,
489            ValueData::Decimal(d) => match other.value {
490                ValueData::Decimal(e) => d.partial_cmp(&e),
491                _ => None, // type error?
492            },
493            ValueData::Integer(d) => match other.value {
494                ValueData::Integer(e) => d.partial_cmp(&e),
495                _ => None, // type error?
496            },
497            ValueData::Double(d) => match other.value {
498                ValueData::Double(e) => d.partial_cmp(&e),
499                _ => None, // type error?
500            },
501            _ => None,
502        }
503    }
504}
505
506//This is ONLY being used for namespace node sorting for the purposes of serializing
507//Feel free to change it.
508//We can change between versions, so long as each execution on that version is consistent.
509impl Ord for Value {
510    fn cmp(&self, other: &Value) -> Ordering {
511        match &self.value {
512            ValueData::String(s) => {
513                let o: String = other.to_string();
514                s.cmp(&o)
515            }
516            ValueData::Boolean(_) => Ordering::Equal,
517            ValueData::Decimal(d) => match other.value {
518                ValueData::Decimal(e) => d.cmp(&e),
519                _ => Ordering::Equal, // type error?
520            },
521            ValueData::Integer(d) => match other.value {
522                ValueData::Integer(e) => d.cmp(&e),
523                _ => Ordering::Equal, // type error?
524            },
525            ValueData::Double(d) => match other.value {
526                ValueData::Double(e) => d.partial_cmp(&e).unwrap_or(Ordering::Equal),
527                _ => Ordering::Equal, // type error?
528            },
529            _ => Ordering::Equal,
530        }
531    }
532}
533
534impl From<String> for Value {
535    fn from(s: String) -> Self {
536        Value {
537            value: ValueData::String(s),
538            output: OutputSpec::Normal,
539        }
540    }
541}
542impl From<&str> for Value {
543    fn from(s: &str) -> Self {
544        Value {
545            value: ValueData::String(String::from(s)),
546            output: OutputSpec::Normal,
547        }
548    }
549}
550impl From<Decimal> for Value {
551    fn from(d: Decimal) -> Self {
552        Value {
553            value: ValueData::Decimal(d),
554            output: OutputSpec::Normal,
555        }
556    }
557}
558impl From<PositiveInteger> for Value {
559    fn from(p: PositiveInteger) -> Self {
560        Value {
561            value: ValueData::PositiveInteger(p),
562            output: OutputSpec::Normal,
563        }
564    }
565}
566impl From<NonPositiveInteger> for Value {
567    fn from(n: NonPositiveInteger) -> Self {
568        Value {
569            value: ValueData::NonPositiveInteger(n),
570            output: OutputSpec::Normal,
571        }
572    }
573}
574impl From<NegativeInteger> for Value {
575    fn from(n: NegativeInteger) -> Self {
576        Value {
577            value: ValueData::NegativeInteger(n),
578            output: OutputSpec::Normal,
579        }
580    }
581}
582impl From<NonNegativeInteger> for Value {
583    fn from(n: NonNegativeInteger) -> Self {
584        Value {
585            value: ValueData::NonNegativeInteger(n),
586            output: OutputSpec::Normal,
587        }
588    }
589}
590impl From<f32> for Value {
591    fn from(f: f32) -> Self {
592        Value {
593            value: ValueData::Float(f),
594            output: OutputSpec::Normal,
595        }
596    }
597}
598impl From<f64> for Value {
599    fn from(f: f64) -> Self {
600        Value {
601            value: ValueData::Double(f),
602            output: OutputSpec::Normal,
603        }
604    }
605}
606impl From<i64> for Value {
607    fn from(i: i64) -> Self {
608        Value {
609            value: ValueData::Integer(i),
610            output: OutputSpec::Normal,
611        }
612    }
613}
614impl From<i32> for Value {
615    fn from(i: i32) -> Self {
616        Value {
617            value: ValueData::Int(i),
618            output: OutputSpec::Normal,
619        }
620    }
621}
622impl From<i16> for Value {
623    fn from(i: i16) -> Self {
624        Value {
625            value: ValueData::Short(i),
626            output: OutputSpec::Normal,
627        }
628    }
629}
630impl From<i8> for Value {
631    fn from(i: i8) -> Self {
632        Value {
633            value: ValueData::Byte(i),
634            output: OutputSpec::Normal,
635        }
636    }
637}
638impl From<u64> for Value {
639    fn from(i: u64) -> Self {
640        Value {
641            value: ValueData::UnsignedLong(i),
642            output: OutputSpec::Normal,
643        }
644    }
645}
646impl From<u32> for Value {
647    fn from(i: u32) -> Self {
648        Value {
649            value: ValueData::UnsignedInt(i),
650            output: OutputSpec::Normal,
651        }
652    }
653}
654impl From<u16> for Value {
655    fn from(i: u16) -> Self {
656        Value {
657            value: ValueData::UnsignedShort(i),
658            output: OutputSpec::Normal,
659        }
660    }
661}
662impl From<u8> for Value {
663    fn from(i: u8) -> Self {
664        Value {
665            value: ValueData::UnsignedByte(i),
666            output: OutputSpec::Normal,
667        }
668    }
669}
670impl From<usize> for Value {
671    fn from(u: usize) -> Self {
672        Value {
673            value: ValueData::UnsignedLong(u.to_u64().unwrap()),
674            output: OutputSpec::Normal,
675        }
676    }
677}
678impl From<bool> for Value {
679    fn from(b: bool) -> Self {
680        Value {
681            value: ValueData::Boolean(b),
682            output: OutputSpec::Normal,
683        }
684    }
685}
686impl From<NormalizedString> for Value {
687    fn from(n: NormalizedString) -> Self {
688        Value {
689            value: ValueData::NormalizedString(n),
690            output: OutputSpec::Normal,
691        }
692    }
693}
694impl From<NCName> for Value {
695    fn from(n: NCName) -> Self {
696        Value {
697            value: ValueData::NCName(n),
698            output: OutputSpec::Normal,
699        }
700    }
701}
702impl From<ID> for Value {
703    fn from(n: ID) -> Self {
704        Value {
705            value: ValueData::ID(n),
706            output: OutputSpec::Normal,
707        }
708    }
709}
710impl From<IDREF> for Value {
711    fn from(n: IDREF) -> Self {
712        Value {
713            value: ValueData::IDREF(n),
714            output: OutputSpec::Normal,
715        }
716    }
717}
718impl From<Vec<IDREF>> for Value {
719    fn from(v: Vec<IDREF>) -> Self {
720        Value {
721            value: ValueData::IDREFS(v),
722            output: OutputSpec::Normal,
723        }
724    }
725}
726impl From<QualifiedName> for Value {
727    fn from(q: QualifiedName) -> Self {
728        Value {
729            value: ValueData::QName(q),
730            output: OutputSpec::Normal,
731        }
732    }
733}
734impl From<Rc<QualifiedName>> for Value {
735    fn from(q: Rc<QualifiedName>) -> Self {
736        Value {
737            value: ValueData::RQName(q),
738            output: OutputSpec::Normal,
739        }
740    }
741}
742impl From<DateTime<Local>> for Value {
743    fn from(d: DateTime<Local>) -> Self {
744        Value {
745            value: ValueData::DateTime(d),
746            output: OutputSpec::Normal,
747        }
748    }
749}
750
751#[derive(Clone, Debug, Hash)]
752pub struct NonPositiveInteger(i64);
753impl TryFrom<i64> for NonPositiveInteger {
754    type Error = Error;
755    fn try_from(v: i64) -> Result<Self, Self::Error> {
756        if v > 0 {
757            Err(Error::new(
758                ErrorKind::TypeError,
759                String::from("NonPositiveInteger must be less than zero"),
760            ))
761        } else {
762            Ok(NonPositiveInteger(v))
763        }
764    }
765}
766impl fmt::Display for NonPositiveInteger {
767    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
768        f.write_str(&self.0.to_string())
769    }
770}
771
772#[derive(Clone, Debug, Hash)]
773pub struct PositiveInteger(i64);
774impl TryFrom<i64> for PositiveInteger {
775    type Error = Error;
776    fn try_from(v: i64) -> Result<Self, Self::Error> {
777        if v <= 0 {
778            Err(Error::new(
779                ErrorKind::TypeError,
780                String::from("PositiveInteger must be greater than zero"),
781            ))
782        } else {
783            Ok(PositiveInteger(v))
784        }
785    }
786}
787impl fmt::Display for PositiveInteger {
788    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
789        f.write_str(&self.0.to_string())
790    }
791}
792
793#[derive(Clone, Debug, Hash)]
794pub struct NonNegativeInteger(i64);
795impl TryFrom<i64> for NonNegativeInteger {
796    type Error = Error;
797    fn try_from(v: i64) -> Result<Self, Self::Error> {
798        if v < 0 {
799            Err(Error::new(
800                ErrorKind::TypeError,
801                String::from("NonNegativeInteger must be zero or greater"),
802            ))
803        } else {
804            Ok(NonNegativeInteger(v))
805        }
806    }
807}
808impl fmt::Display for NonNegativeInteger {
809    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
810        f.write_str(&self.0.to_string())
811    }
812}
813
814#[derive(Clone, Debug, Hash)]
815pub struct NegativeInteger(i64);
816impl TryFrom<i64> for NegativeInteger {
817    type Error = Error;
818    fn try_from(v: i64) -> Result<Self, Self::Error> {
819        if v >= 0 {
820            Err(Error::new(
821                ErrorKind::TypeError,
822                String::from("NegativeInteger must be less than zero"),
823            ))
824        } else {
825            Ok(NegativeInteger(v))
826        }
827    }
828}
829impl fmt::Display for NegativeInteger {
830    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
831        f.write_str(&self.0.to_string())
832    }
833}
834
835#[derive(Clone, Debug, Hash)]
836pub struct NormalizedString(String);
837impl TryFrom<&str> for NormalizedString {
838    type Error = Error;
839    fn try_from(v: &str) -> Result<Self, Self::Error> {
840        let n: &[_] = &['\n', '\r', '\t'];
841        if v.find(n).is_none() {
842            Ok(NormalizedString(v.to_string()))
843        } else {
844            Err(Error::new(
845                ErrorKind::TypeError,
846                String::from("value is not a normalized string"),
847            ))
848        }
849    }
850}
851impl fmt::Display for NormalizedString {
852    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
853        f.write_str(&self.0.to_string())
854    }
855}
856
857/// An XML Name (XML production 5):
858/// Name ::= NameStartChar NameChar*
859#[derive(Clone, Debug, Hash)]
860pub struct Name(String);
861impl TryFrom<&str> for Name {
862    type Error = Error;
863    fn try_from(v: &str) -> Result<Self, Self::Error> {
864        // TODO: do a proper check
865        let n: &[_] = &['\n', '\r', '\t'];
866        if v.find(n).is_none() {
867            Ok(Name(v.to_string()))
868        } else {
869            Err(Error::new(
870                ErrorKind::TypeError,
871                String::from("value is not a Name"),
872            ))
873        }
874    }
875}
876impl fmt::Display for Name {
877    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
878        f.write_str(&self.0.to_string())
879    }
880}
881
882/// An XML Entity (XML production 56) must match the Name production (5):
883/// Name ::= NameStartChar NameChar*
884#[derive(Clone, Debug, Hash)]
885pub struct ENTITY(String);
886impl TryFrom<&str> for ENTITY {
887    type Error = Error;
888    fn try_from(v: &str) -> Result<Self, Self::Error> {
889        // TODO: do a proper check
890        let n: &[_] = &['\n', '\r', '\t'];
891        if v.find(n).is_none() {
892            Ok(ENTITY(v.to_string()))
893        } else {
894            Err(Error::new(
895                ErrorKind::TypeError,
896                String::from("value is not an ENTITY"),
897            ))
898        }
899    }
900}
901impl fmt::Display for ENTITY {
902    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
903        f.write_str(&self.0.to_string())
904    }
905}
906
907/// An XML NMTOKEN (XML production 56) must match the Nmtoken production (7):
908/// Nmtoken ::= NameChar+
909#[derive(Clone, Debug, Hash)]
910pub struct NMTOKEN(String);
911impl TryFrom<&str> for NMTOKEN {
912    type Error = Error;
913    fn try_from(v: &str) -> Result<Self, Self::Error> {
914        // TODO: do a proper check
915        if !v.is_empty() {
916            Ok(NMTOKEN(v.to_string()))
917        } else {
918            Err(Error::new(
919                ErrorKind::TypeError,
920                String::from("value is not a NMTOKEN"),
921            ))
922        }
923    }
924}
925impl fmt::Display for NMTOKEN {
926    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
927        f.write_str(&self.0.to_string())
928    }
929}
930
931/// An XML ID (XML production 56) must match the Name production (5):
932/// Name ::= NameStartChar NameChar*
933/// An ID must be unique within a document. It is the responsibility of the document to check for compliance.
934#[derive(Clone, Debug, Hash)]
935pub struct ID(String);
936impl TryFrom<&str> for ID {
937    type Error = Error;
938    fn try_from(v: &str) -> Result<Self, Self::Error> {
939        // TODO: An XML ID must be a Name
940        let n: &[_] = &['\n', '\r', '\t'];
941        if v.find(n).is_none() {
942            Ok(ID(v.to_string()))
943        } else {
944            Err(Error::new(
945                ErrorKind::TypeError,
946                String::from("value is not an ID"),
947            ))
948        }
949    }
950}
951impl TryFrom<String> for ID {
952    type Error = Error;
953    fn try_from(v: String) -> Result<Self, Self::Error> {
954        // TODO: An XML ID must be a Name
955        let n: &[_] = &['\n', '\r', '\t'];
956        if v.find(n).is_none() {
957            Ok(ID(v))
958        } else {
959            Err(Error::new(
960                ErrorKind::TypeError,
961                String::from("value is not an ID"),
962            ))
963        }
964    }
965}
966impl fmt::Display for ID {
967    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
968        f.write_str(&self.0.to_string())
969    }
970}
971
972/// An XML IDREF (XML production 56) must match the Name production (5):
973/// Name ::= NameStartChar NameChar*
974#[derive(Clone, Debug, Hash)]
975pub struct IDREF(String);
976impl TryFrom<&str> for IDREF {
977    type Error = Error;
978    fn try_from(v: &str) -> Result<Self, Self::Error> {
979        // TODO: An XML IDREF must be a Name
980        let n: &[_] = &['\n', '\r', '\t'];
981        if v.find(n).is_none() {
982            Ok(IDREF(v.to_string()))
983        } else {
984            Err(Error::new(
985                ErrorKind::TypeError,
986                String::from("value is not an IDREF"),
987            ))
988        }
989    }
990}
991impl TryFrom<String> for IDREF {
992    type Error = Error;
993    fn try_from(v: String) -> Result<Self, Self::Error> {
994        // TODO: An XML IDREF must be a Name
995        let n: &[_] = &['\n', '\r', '\t'];
996        if v.find(n).is_none() {
997            Ok(IDREF(v))
998        } else {
999            Err(Error::new(
1000                ErrorKind::TypeError,
1001                String::from("value is not an IDREF"),
1002            ))
1003        }
1004    }
1005}
1006impl fmt::Display for IDREF {
1007    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1008        f.write_str(&self.0.to_string())
1009    }
1010}
1011
1012/// An NCName for XML Namespaces.
1013#[derive(Clone, Debug, Hash)]
1014pub struct NCName(String);
1015impl TryFrom<&str> for NCName {
1016    type Error = Error;
1017    fn try_from(v: &str) -> Result<Self, Self::Error> {
1018        // TODO: do a proper check
1019        let n: &[_] = &['\n', '\r', '\t', ':'];
1020        if v.find(n).is_none() {
1021            Ok(NCName(v.to_string()))
1022        } else {
1023            Err(Error::new(
1024                ErrorKind::TypeError,
1025                String::from("value is not a NCName"),
1026            ))
1027        }
1028    }
1029}
1030impl fmt::Display for NCName {
1031    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1032        f.write_str(&self.0.to_string())
1033    }
1034}
1035
1036#[cfg(test)]
1037mod tests {
1038    use super::*;
1039
1040    #[test]
1041    fn from_string() {
1042        assert_eq!(Value::from(String::from("foobar")).to_string(), "foobar");
1043    }
1044    #[test]
1045    fn from_str() {
1046        assert_eq!(Value::from("foobar").to_string(), "foobar");
1047    }
1048    #[test]
1049    fn from_decimal() {
1050        assert_eq!(Value::from(dec!(001.23)).to_string(), "1.23");
1051    }
1052
1053    #[test]
1054    fn normalizedstring_valid_empty() {
1055        assert_eq!(
1056            NormalizedString::try_from("")
1057                .expect("invalid NormalizedString")
1058                .0,
1059            ""
1060        );
1061    }
1062    #[test]
1063    fn normalizedstring_valid() {
1064        assert_eq!(
1065            NormalizedString::try_from("notinvalid")
1066                .expect("invalid NormalizedString")
1067                .0,
1068            "notinvalid"
1069        );
1070    }
1071    #[test]
1072    fn normalizedstring_valid_spaces() {
1073        assert_eq!(
1074            NormalizedString::try_from("not an invalid string")
1075                .expect("invalid NormalizedString")
1076                .0,
1077            "not an invalid string"
1078        );
1079    }
1080    #[test]
1081    fn normalizedstring_invalid_tab() {
1082        let r = NormalizedString::try_from("contains tab	character");
1083        assert!(match r {
1084            Ok(_) => panic!("string contains tab character"),
1085            Err(_) => true,
1086        })
1087    }
1088    #[test]
1089    fn normalizedstring_invalid_newline() {
1090        let r = NormalizedString::try_from("contains newline\ncharacter");
1091        assert!(match r {
1092            Ok(_) => panic!("string contains newline character"),
1093            Err(_) => true,
1094        })
1095    }
1096    #[test]
1097    fn normalizedstring_invalid_cr() {
1098        let r = NormalizedString::try_from("contains carriage return\rcharacter");
1099        assert!(match r {
1100            Ok(_) => panic!("string contains cr character"),
1101            Err(_) => true,
1102        })
1103    }
1104    #[test]
1105    fn normalizedstring_invalid_all() {
1106        let r = NormalizedString::try_from("contains	all\rforbidden\ncharacters");
1107        assert!(match r {
1108            Ok(_) => panic!("string contains at least one forbidden character"),
1109            Err(_) => true,
1110        })
1111    }
1112
1113    // Numeric is in the too hard basket for now
1114    //    #[test]
1115    //    fn numeric_float() {
1116    //        assert_eq!(Numeric::new(f32::0.123).value, 0.123);
1117    //    }
1118    //    #[test]
1119    //    fn numeric_double() {
1120    //        assert_eq!(Numeric::new(f64::0.456).value, 0.456);
1121    //    }
1122    //    #[test]
1123    //    fn numeric_decimal() {
1124    //        assert_eq!(Numeric::new(dec!(123.456)), 123.456);
1125    //    }
1126
1127    #[test]
1128    fn nonpositiveinteger_valid() {
1129        assert_eq!(
1130            NonPositiveInteger::try_from(-10)
1131                .expect("invalid NonPositiveInteger")
1132                .0,
1133            -10
1134        );
1135    }
1136    #[test]
1137    fn nonpositiveinteger_valid_zero() {
1138        assert_eq!(
1139            NonPositiveInteger::try_from(0)
1140                .expect("invalid NonPositiveInteger")
1141                .0,
1142            0
1143        );
1144    }
1145    #[test]
1146    fn nonpositiveinteger_invalid() {
1147        let r = NonPositiveInteger::try_from(10);
1148        assert!(match r {
1149            Ok(_) => panic!("10 is not a nonPositiveInteger"),
1150            Err(_) => true,
1151        })
1152    }
1153
1154    #[test]
1155    fn positiveinteger_valid() {
1156        assert_eq!(
1157            PositiveInteger::try_from(10)
1158                .expect("invalid PositiveInteger")
1159                .0,
1160            10
1161        );
1162    }
1163    #[test]
1164    fn positiveinteger_invalid_zero() {
1165        let r = PositiveInteger::try_from(0);
1166        assert!(match r {
1167            Ok(_) => panic!("0 is not a PositiveInteger"),
1168            Err(_) => true,
1169        })
1170    }
1171    #[test]
1172    fn positiveinteger_invalid() {
1173        let r = PositiveInteger::try_from(-10);
1174        assert!(match r {
1175            Ok(_) => panic!("-10 is not a PositiveInteger"),
1176            Err(_) => true,
1177        })
1178    }
1179
1180    #[test]
1181    fn nonnegativeinteger_valid() {
1182        assert_eq!(
1183            NonNegativeInteger::try_from(10)
1184                .expect("invalid NonNegativeInteger")
1185                .0,
1186            10
1187        );
1188    }
1189    #[test]
1190    fn nonnegativeinteger_valid_zero() {
1191        assert_eq!(
1192            NonNegativeInteger::try_from(0)
1193                .expect("invalid NonNegativeInteger")
1194                .0,
1195            0
1196        );
1197    }
1198    #[test]
1199    fn nonnegativeinteger_invalid() {
1200        let r = NonNegativeInteger::try_from(-10);
1201        assert!(match r {
1202            Ok(_) => panic!("-10 is not a NonNegativeInteger"),
1203            Err(_) => true,
1204        })
1205    }
1206
1207    #[test]
1208    fn negativeinteger_valid() {
1209        assert_eq!(
1210            NegativeInteger::try_from(-10)
1211                .expect("invalid NegativeInteger")
1212                .0,
1213            -10
1214        );
1215    }
1216    #[test]
1217    fn negativeinteger_invalid_zero() {
1218        let r = NegativeInteger::try_from(0);
1219        assert!(match r {
1220            Ok(_) => panic!("0 is not a NegativeInteger"),
1221            Err(_) => true,
1222        })
1223    }
1224    #[test]
1225    fn negativeinteger_invalid() {
1226        let r = NegativeInteger::try_from(10);
1227        assert!(match r {
1228            Ok(_) => panic!("10 is not a NegativeInteger"),
1229            Err(_) => true,
1230        })
1231    }
1232
1233    // String Values
1234    #[test]
1235    fn string_strvalue() {
1236        assert_eq!(Value::from("foobar").to_string(), "foobar")
1237    }
1238    #[test]
1239    fn string_stringvalue() {
1240        assert_eq!(Value::from("foobar".to_string()).to_string(), "foobar")
1241    }
1242    #[test]
1243    fn decimal_stringvalue() {
1244        assert_eq!(Value::from(dec!(001.23)).to_string(), "1.23")
1245    }
1246    #[test]
1247    fn float_stringvalue() {
1248        assert_eq!(Value::from(001.2300_f32).to_string(), "1.23")
1249    }
1250    #[test]
1251    fn nonpositiveinteger_stringvalue() {
1252        let npi = NonPositiveInteger::try_from(-00123).expect("invalid nonPositiveInteger");
1253        let i = Value::from(npi);
1254        assert_eq!(i.to_string(), "-123")
1255    }
1256    #[test]
1257    fn nonnegativeinteger_stringvalue() {
1258        let nni = NonNegativeInteger::try_from(00123).expect("invalid nonNegativeInteger");
1259        let i = Value::from(nni);
1260        assert_eq!(i.to_string(), "123")
1261    }
1262    #[test]
1263    fn normalizedstring_stringvalue() {
1264        let ns = NormalizedString::try_from("foobar").expect("invalid normalizedString");
1265        let i = Value::from(ns);
1266        assert_eq!(i.to_string(), "foobar")
1267    }
1268
1269    // value to_bool
1270
1271    #[test]
1272    fn value_to_bool_string() {
1273        assert!(Value::from("2").to_bool())
1274    }
1275
1276    // value to_int
1277
1278    #[test]
1279    fn value_to_int_string() {
1280        assert_eq!(
1281            Value::from("2")
1282                .to_int()
1283                .expect("cannot convert to integer"),
1284            2
1285        )
1286    }
1287
1288    // value to_double
1289
1290    #[test]
1291    fn value_to_double_string() {
1292        assert_eq!(Value::from("3.0").to_double(), 3.0)
1293    }
1294
1295    // value compare
1296
1297    #[test]
1298    fn value_compare_eq() {
1299        assert!(
1300            Value::from("3")
1301                .compare(&Value::from(3.0), Operator::Equal)
1302                .expect("unable to compare")
1303        )
1304    }
1305
1306    #[test]
1307    fn value_compare_ne() {
1308        assert!(
1309            !Value::from("3")
1310                .compare(&Value::from(3.0), Operator::NotEqual)
1311                .expect("unable to compare")
1312        )
1313    }
1314
1315    //#[test]
1316    //fn value_atomize() {
1317    //let i = Value::Int(123);
1318    //assert_eq!(i.atomize().stringvalue(), "123")
1319    //}
1320
1321    // Operators
1322    #[test]
1323    fn op_equal() {
1324        assert_eq!(Operator::Equal.to_string(), "=")
1325    }
1326    #[test]
1327    fn op_notequal() {
1328        assert_eq!(Operator::NotEqual.to_string(), "!=")
1329    }
1330    #[test]
1331    fn op_lt() {
1332        assert_eq!(Operator::LessThan.to_string(), "<")
1333    }
1334    #[test]
1335    fn op_ltequal() {
1336        assert_eq!(Operator::LessThanEqual.to_string(), "<=")
1337    }
1338    #[test]
1339    fn op_gt() {
1340        assert_eq!(Operator::GreaterThan.to_string(), ">")
1341    }
1342    #[test]
1343    fn op_gtequal() {
1344        assert_eq!(Operator::GreaterThanEqual.to_string(), ">=")
1345    }
1346    #[test]
1347    fn op_is() {
1348        assert_eq!(Operator::Is.to_string(), "is")
1349    }
1350    #[test]
1351    fn op_before() {
1352        assert_eq!(Operator::Before.to_string(), "<<")
1353    }
1354    #[test]
1355    fn op_after() {
1356        assert_eq!(Operator::After.to_string(), ">>")
1357    }
1358
1359    // Building a value
1360    #[test]
1361    fn build_1() {
1362        let v = ValueBuilder::new()
1363            .value(ValueData::String(String::from("test value")))
1364            .build();
1365        assert_eq!(v.to_string(), "test value");
1366        assert_eq!(v.output_ref(), &OutputSpec::Normal)
1367    }
1368    #[test]
1369    fn build_2() {
1370        let v = ValueBuilder::new()
1371            .value(ValueData::String(String::from("test value")))
1372            .output(OutputSpec::Escaped)
1373            .build();
1374        assert_eq!(v.to_string(), "test value");
1375        assert_eq!(v.output_ref(), &OutputSpec::Escaped)
1376    }
1377}