1#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6pub struct OwningChars {
7 #[cfg_attr(
10 feature = "serde",
11 serde(
12 serialize_with = "crate::serde_tools::serialize_str",
13 deserialize_with = "crate::serde_tools::deserialize_rc_str"
14 )
15 )]
16 s: std::rc::Rc<str>,
17 pos: usize,
18}
19
20impl OwningChars {
21 pub fn new(s: std::rc::Rc<str>) -> OwningChars {
22 OwningChars { s, pos: 0 }
23 }
24
25 pub fn str(&self) -> &str {
26 &self.s
27 }
28
29 #[inline]
30 pub fn peek(&self) -> Option<char> {
31 self.s[self.pos..].chars().next()
32 }
33}
34
35impl std::iter::Iterator for OwningChars {
36 type Item = char;
37
38 #[inline]
39 fn next(&mut self) -> Option<Self::Item> {
40 let c_opt = self.s[self.pos..].chars().next();
41 if let Some(c) = c_opt {
42 self.pos += c.len_utf8();
43 }
44 c_opt
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn base_case() {
54 let s: std::rc::Rc<str> = "Tör".into();
55 let mut iter = OwningChars::new(s);
56 assert_eq!(Some('T'), iter.next());
57 assert_eq!(Some('ö'), iter.next());
58 assert_eq!(Some('r'), iter.next());
59 assert_eq!(None, iter.next());
60 }
61}