1use std::ops::{Deref, DerefMut, Index};
2
3use detached_str::{Str, StrSlice};
4
5use crate::{Parse, ParseInfallible};
6
7#[derive(Debug, Clone)]
8pub struct Input {
9 pub text: Str,
10 idx: usize,
11}
12
13impl Input {
14 pub fn new(text: impl ToString) -> Self {
15 Input { text: text.to_string().into(), idx: 0 }
16 }
17
18 #[must_use]
19 pub fn start(&mut self) -> ModifyInput<'_> {
20 let prev_idx = self.idx;
21 ModifyInput { input: self, prev_idx }
22 }
23
24 pub fn len(&self) -> usize {
25 self.text.len() - self.idx
26 }
27
28 pub fn is_empty(&self) -> bool {
29 self.len() == 0
30 }
31
32 pub fn rest(&self) -> &str {
33 &self.text[self.idx as usize..]
34 }
35
36 #[cfg(test)]
37 pub fn prev(&self) -> &str {
38 &self.text[..self.idx as usize]
39 }
40
41 pub fn prev_slice_bytes(&self, bytes: usize) -> StrSlice {
42 self.text.get(self.idx - bytes..self.idx)
43 }
44
45 pub fn bump(&mut self, bytes: usize) -> StrSlice {
46 self.idx += bytes;
47 self.text.get(self.idx - bytes..self.idx)
48 }
49
50 pub fn peek_char(&self) -> Option<char> {
51 self.rest().chars().next()
52 }
53
54 pub fn prev_char(&self) -> Option<char> {
55 let parsed = &self.text[..self.idx as usize];
56 parsed.chars().last()
57 }
58
59 #[must_use]
63 pub fn parse<P: Parse>(&mut self, mut parser: P) -> Option<P::Output> {
64 parser.parse(self)
65 }
66
67 pub fn parse_i<P: ParseInfallible>(&mut self, parser: P) -> P::Output {
70 parser.parse_infallible(self)
71 }
72
73 pub fn try_parse<P: Parse>(&mut self, mut parser: P) {
76 parser.parse(self);
77 }
78
79 pub fn can_parse<P: Parse>(&mut self, mut parser: P) -> bool {
82 parser.can_parse(self)
83 }
84}
85
86pub struct ModifyInput<'a> {
87 input: &'a mut Input,
88 prev_idx: usize,
89}
90
91impl ModifyInput<'_> {
92 pub fn apply(mut self) -> StrSlice {
93 let prev = self.prev_idx;
94 self.prev_idx = self.input.idx;
95 self.prev_slice_bytes(self.input.idx - prev)
96 }
97}
98
99impl Deref for ModifyInput<'_> {
100 type Target = Input;
101
102 fn deref(&self) -> &Self::Target {
103 self.input
104 }
105}
106
107impl DerefMut for ModifyInput<'_> {
108 fn deref_mut(&mut self) -> &mut Self::Target {
109 self.input
110 }
111}
112
113impl<'a> AsRef<Input> for ModifyInput<'a> {
114 fn as_ref(&self) -> &Input {
115 self.input
116 }
117}
118
119impl<'a> AsMut<Input> for ModifyInput<'a> {
120 fn as_mut(&mut self) -> &mut Input {
121 self.input
122 }
123}
124
125impl Drop for ModifyInput<'_> {
126 fn drop(&mut self) {
127 self.input.idx = self.prev_idx;
128 }
129}
130
131impl Index<StrSlice> for Input {
132 type Output = str;
133
134 fn index(&self, index: StrSlice) -> &Self::Output {
135 &self.text[index.range()]
136 }
137}
138
139#[test]
140fn test_bump() {
141 let mut input = Input::new("abcd");
142 assert_eq!(input.rest(), "abcd");
143 input.bump(2);
144 assert_eq!(input.rest(), "cd");
145 input.bump(2);
146 assert_eq!(input.rest(), "");
147}
148
149#[test]
150fn test_modify() {
151 let mut input = Input::new("abcdef");
152 {
153 let mut input2 = input.start();
154 input2.bump(1);
155 assert_eq!(input2.rest(), "bcdef");
156 }
157 assert_eq!(input.rest(), "abcdef");
158
159 {
160 let mut input3 = input.start();
161 input3.bump(1);
162 input3.apply();
163 }
164 assert_eq!(input.rest(), "bcdef");
165
166 {
167 let mut input4 = input.start();
168 input4.bump(1);
169 {
170 let mut input5 = input4.start();
171 input5.bump(2);
172 input5.apply();
173 }
174 }
175 assert_eq!(input.rest(), "bcdef");
176
177 {
178 let mut input6 = input.start();
179 input6.bump(1);
180 {
181 let mut input7 = input6.start();
182 input7.bump(2);
183 }
184 input6.apply();
185 }
186 assert_eq!(input.rest(), "cdef");
187
188 {
189 let mut input8 = input.start();
190 input8.bump(1);
191 {
192 let mut input9 = input8.start();
193 input9.bump(2);
194 input9.apply();
195 }
196 input8.apply();
197 }
198 assert_eq!(input.rest(), "f");
199
200 {
201 let mut input8 = input.start();
202 input8.bump(1);
203 }
204
205 assert_eq!(input.prev(), "abcde");
206}