1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use crate::JsonPointer;
use crate::parser::ParseError;
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum Token {
Slash,
Literal(char),
Escaped(Escape),
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum Escape {
Tilde = 0,
Slash = 1,
}
impl Into<char> for Escape {
fn into(self) -> char {
match self {
Escape::Tilde => '~',
Escape::Slash => '/',
}
}
}
pub fn parse<II: IntoIterator<Item=char>>(ii: II) -> Result<JsonPointer<String, Vec<String>>, ParseError> {
let toks = Tokenizer::new(ii).collect::<Result<Vec<_>, _>>()?;
let mut iter = toks.split(|t| t == &Token::Slash);
if iter.next().map(|s| s.len() > 0).unwrap_or(false) {
return Err(ParseError::NoLeadingSlash);
}
let mut parts = Vec::new();
for s in iter {
let mut part = String::new();
for ch in s {
part.push(match *ch {
Token::Slash => unreachable!(),
Token::Literal(c) => c,
Token::Escaped(e) => e.into(),
});
}
parts.push(part);
}
Ok(JsonPointer::new(parts.into_iter().collect()))
}
pub struct Tokenizer<I: Iterator<Item=char>> {
iter: I,
}
impl<I: Iterator<Item=char>> Tokenizer<I> {
pub fn new<II: IntoIterator<Item=char, IntoIter=I>>(ii: II) -> Tokenizer<I> {
Tokenizer {
iter: ii.into_iter(),
}
}
}
impl<I: Iterator<Item=char>> Iterator for Tokenizer<I> {
type Item = Result<Token, ParseError>;
fn next(&mut self) -> Option<Self::Item> {
match self.iter.next() {
Some('/') => Some(Ok(Token::Slash)),
Some('~') => match self.iter.next() {
Some('0') => Some(Ok(Token::Escaped(Escape::Tilde))),
Some('1') => Some(Ok(Token::Escaped(Escape::Slash))),
Some(c) => Some(Err(ParseError::InvalidEscape(format!("~{}", c)))),
None => Some(Err(ParseError::InvalidEscape("~".to_string()))),
},
Some(c) => Some(Ok(Token::Literal(c))),
None => None,
}
}
}