1use std::fmt;
4
5#[derive(Copy, Clone, PartialEq, Eq)]
7pub struct TextPosition {
8 pub row: u64,
10 pub column: u64,
12}
13
14impl TextPosition {
15 #[inline]
17 pub fn new() -> TextPosition {
18 TextPosition { row: 0, column: 0 }
19 }
20
21 #[inline]
23 pub fn advance(&mut self, count: u8) {
24 self.column += count as u64;
25 }
26
27 #[inline]
29 pub fn advance_to_tab(&mut self, width: u8) {
30 let width = width as u64;
31 self.column += width - self.column % width
32 }
33
34 #[inline]
36 pub fn new_line(&mut self) {
37 self.column = 0;
38 self.row += 1;
39 }
40}
41
42impl fmt::Debug for TextPosition {
43 #[inline]
44 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
45 write!(f, "{}:{}", self.row + 1, self.column + 1)
46 }
47}
48
49impl fmt::Display for TextPosition {
50 #[inline]
51 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
52 write!(f, "{}:{}", self.row + 1, self.column + 1)
53 }
54}
55
56pub trait Position {
60 fn position(&self) -> TextPosition;
62}
63
64impl Position for TextPosition {
65 #[inline]
66 fn position(&self) -> TextPosition {
67 *self
68 }
69}
70
71#[derive(Copy, Clone, PartialEq, Eq)]
73pub enum XmlVersion {
74 Version10,
76
77 Version11
79}
80
81impl fmt::Display for XmlVersion {
82 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
83 match *self {
84 XmlVersion::Version10 => write!(f, "1.0"),
85 XmlVersion::Version11 => write!(f, "1.1")
86 }
87 }
88}
89
90impl fmt::Debug for XmlVersion {
91 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
92 fmt::Display::fmt(self, f)
93 }
94}
95
96pub fn is_whitespace_char(c: char) -> bool {
101 match c {
102 '\x20' | '\x09' | '\x0d' | '\x0a' => true,
103 _ => false
104 }
105}
106
107pub fn is_whitespace_str(s: &str) -> bool {
111 s.chars().all(is_whitespace_char)
112}
113
114pub fn is_name_start_char(c: char) -> bool {
119 match c {
120 ':' | 'A'...'Z' | '_' | 'a'...'z' |
121 '\u{C0}'...'\u{D6}' | '\u{D8}'...'\u{F6}' | '\u{F8}'...'\u{2FF}' |
122 '\u{370}'...'\u{37D}' | '\u{37F}'...'\u{1FFF}' |
123 '\u{200C}'...'\u{200D}' | '\u{2070}'...'\u{218F}' |
124 '\u{2C00}'...'\u{2FEF}' | '\u{3001}'...'\u{D7FF}' |
125 '\u{F900}'...'\u{FDCF}' | '\u{FDF0}'...'\u{FFFD}' |
126 '\u{10000}'...'\u{EFFFF}' => true,
127 _ => false
128 }
129}
130
131pub fn is_name_char(c: char) -> bool {
136 match c {
137 _ if is_name_start_char(c) => true,
138 '-' | '.' | '0'...'9' | '\u{B7}' |
139 '\u{300}'...'\u{3F6}' | '\u{203F}'...'\u{2040}' => true,
140 _ => false
141 }
142}