1use crate::ToFormatParser;
2
3#[derive(Debug, Clone, Copy)]
4#[non_exhaustive]
6pub enum ParseSegment<'a> {
7 Literal(&'a str),
9 Key(&'a str),
11}
12
13impl Default for ParseSegment<'_> {
14 fn default() -> Self {
15 Self::Literal("")
16 }
17}
18
19pub struct FromStr<'a> {
21 pub(crate) s: &'a str,
22 pub(crate) is_key: bool,
23}
24
25impl<'a> Iterator for FromStr<'a> {
26 type Item = ParseSegment<'a>;
27
28 fn next(&mut self) -> Option<Self::Item> {
29 if self.s.is_empty() {
30 None
31 } else if self.is_key {
32 match self.s.strip_prefix('{') {
33 Some(rest) => match rest.split_once('{') {
35 None => {
36 self.is_key = false;
37 Some(ParseSegment::Literal(core::mem::take(&mut self.s)))
38 }
39 Some((prefix, rest)) => {
40 let x = &self.s[..prefix.len() + 1];
41 self.s = rest;
42 Some(ParseSegment::Literal(x))
43 }
44 },
45 None => match self.s.split_once('}') {
46 Some((key, rest)) => {
47 self.is_key = false;
48 self.s = rest;
49 Some(ParseSegment::Key(key))
50 }
51 None => None,
52 },
53 }
54 } else {
55 match self.s.split_once('{') {
56 None => Some(ParseSegment::Literal(core::mem::take(&mut self.s))),
57 Some((prefix, rest)) => {
58 self.is_key = true;
59 self.s = rest;
60 Some(ParseSegment::Literal(prefix))
61 }
62 }
63 }
64 }
65}
66
67impl<'a> ToFormatParser<'a> for str {
68 type Parser = FromStr<'a>;
69
70 fn to_parser(&'a self) -> Self::Parser {
71 FromStr {
72 s: self,
73 is_key: false,
74 }
75 }
76
77 fn unparsed(iter: Self::Parser) -> &'a str {
78 iter.s
79 }
80}