Skip to main content

xrust/
value.rs

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