1pub type Pos = u32;
3
4pub type Span = (Pos, Pos);
7
8pub trait HasSpan {
9 fn span(&self) -> Span;
10}
11
12#[derive(Debug, Clone)]
16pub struct Cursor<I> {
17 input: I,
19 cur_pos: u32,
21}
22
23impl<I> Cursor<I> {
24 pub fn new(input: I) -> Cursor<I> {
25 Cursor { input, cur_pos: 0 }
26 }
27
28 pub fn pos(&self) -> Pos {
29 self.cur_pos
30 }
31}
32
33impl<I: Iterator<Item = char> + Clone> Cursor<I> {
34 pub fn first(&self) -> Option<char> {
35 self.input.clone().next()
36 }
37}
38
39impl<I: Iterator<Item = char>> Iterator for Cursor<I> {
40 type Item = char;
41 fn next(&mut self) -> Option<char> {
42 let c = self.input.next();
43 if c.is_some() {
44 self.cur_pos += 1;
45 }
46 c
47 }
48}
49
50#[test]
51fn test_cursor() {
52 let mut c = Cursor::new("some string".chars());
53 assert_eq!(c.pos(), 0);
54 assert_eq!(c.next(), Some('s'));
55 assert_eq!(c.next(), Some('o'));
56 assert_eq!(c.next(), Some('m'));
57 assert_eq!(c.next(), Some('e'));
58 assert_eq!(c.pos(), 4);
59 assert_eq!(c.first(), Some(' '));
60 assert_eq!(c.pos(), 4);
61 assert_eq!(c.next(), Some(' '));
62 assert_eq!(c.pos(), 5);
63
64 let mut cl = c.clone();
65 assert_eq!(cl.pos(), 5);
66 assert_eq!(cl.next(), Some('s'));
67 assert_eq!(cl.next(), Some('t'));
68 assert_eq!(cl.pos(), 7);
69
70 assert_eq!(c.pos(), 5);
71 assert_eq!(c.next(), Some('s'));
72 assert_eq!(c.next(), Some('t'));
73 assert_eq!(c.next(), Some('r'));
74 assert_eq!(c.next(), Some('i'));
75 assert_eq!(c.next(), Some('n'));
76 assert_eq!(c.pos(), 10);
77 assert_eq!(c.next(), Some('g'));
78 assert_eq!(c.pos(), 11);
79 assert_eq!(c.next(), None);
80}