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
use crate::{ToFormatParser};
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
pub enum ParseSegment<'a> {
Literal(&'a str),
Key(&'a str),
}
impl Default for ParseSegment<'_> {
fn default() -> Self {
Self::Literal("")
}
}
pub struct FromStr<'a> {
pub(crate) s: &'a str,
pub(crate) is_key: bool,
}
impl<'a> Iterator for FromStr<'a> {
type Item = ParseSegment<'a>;
fn next(&mut self) -> Option<Self::Item> {
if self.s.is_empty() {
None
} else if self.is_key {
match self.s.strip_prefix('{') {
Some(rest) => match rest.split_once('{') {
None => {
self.is_key = false;
Some(ParseSegment::Literal(core::mem::take(&mut self.s)))
}
Some((prefix, rest)) => {
let x = &self.s[..prefix.len() + 1];
self.s = rest;
Some(ParseSegment::Literal(x))
}
},
None => match self.s.split_once('}') {
Some((key, rest)) => {
self.is_key = false;
self.s = rest;
Some(ParseSegment::Key(key))
}
None => None,
},
}
} else {
match self.s.split_once('{') {
None => Some(ParseSegment::Literal(core::mem::take(&mut self.s))),
Some((prefix, rest)) => {
self.is_key = true;
self.s = rest;
Some(ParseSegment::Literal(prefix))
}
}
}
}
}
impl<'a> ToFormatParser<'a> for str {
type Parser = FromStr<'a>;
fn to_parser(&'a self) -> Self::Parser {
FromStr {
s: self,
is_key: false,
}
}
fn unparsed(iter: Self::Parser) -> &'a str {
iter.s
}
}