ca_formats/
input.rs

1use std::{
2    io::{BufRead, BufReader, Error, Lines as IoLines, Read},
3    str::{Bytes, Lines},
4    vec::IntoIter,
5};
6
7/// Types that can be passed to parsers as input.
8///
9/// The trait is implemented for `&str`, `&[u8]`, [`BufReader`],
10/// and `&mut B` for every type `B` that implements [`BufRead`].
11///
12/// When parsing a file, you can take a [`BufReader<File>`] as input.
13pub trait Input {
14    /// An iterator over lines of the input.
15    type Lines: Iterator;
16    /// A string or a reference to a string, which represents a line of the input.
17    type Line: AsRef<str>;
18    /// An iterator over bytes of a line.
19    type Bytes: Iterator<Item = u8>;
20
21    /// Creates an iterator over lines from the input.
22    fn lines(self) -> Self::Lines;
23
24    /// Converts a item in the lines iterator to a string.
25    fn line(item: <Self::Lines as Iterator>::Item) -> Result<Self::Line, Error>;
26
27    /// Creates an iterator over bytes from a line.
28    fn bytes(line: Self::Line) -> Self::Bytes;
29}
30
31impl<'a> Input for &'a str {
32    type Lines = Lines<'a>;
33    type Line = &'a str;
34    type Bytes = Bytes<'a>;
35
36    fn lines(self) -> Self::Lines {
37        self.lines()
38    }
39
40    fn line(item: <Self::Lines as Iterator>::Item) -> Result<Self::Line, Error> {
41        Ok(item)
42    }
43
44    fn bytes(line: Self::Line) -> Self::Bytes {
45        line.bytes()
46    }
47}
48
49impl<'a> Input for Lines<'a> {
50    type Lines = Self;
51    type Line = &'a str;
52    type Bytes = Bytes<'a>;
53
54    fn lines(self) -> Self::Lines {
55        self
56    }
57
58    fn line(item: <Self::Lines as Iterator>::Item) -> Result<Self::Line, Error> {
59        Ok(item)
60    }
61
62    fn bytes(line: Self::Line) -> Self::Bytes {
63        line.bytes()
64    }
65}
66
67impl<'a> Input for &'a [u8] {
68    type Lines = IoLines<Self>;
69    type Line = String;
70    type Bytes = IntoIter<u8>;
71
72    fn lines(self) -> Self::Lines {
73        BufRead::lines(self)
74    }
75
76    fn line(item: <Self::Lines as Iterator>::Item) -> Result<Self::Line, Error> {
77        item
78    }
79
80    fn bytes(line: Self::Line) -> Self::Bytes {
81        line.into_bytes().into_iter()
82    }
83}
84
85impl<R: Read> Input for BufReader<R> {
86    type Lines = IoLines<Self>;
87    type Line = String;
88    type Bytes = IntoIter<u8>;
89
90    fn lines(self) -> Self::Lines {
91        BufRead::lines(self)
92    }
93
94    fn line(item: <Self::Lines as Iterator>::Item) -> Result<Self::Line, Error> {
95        item
96    }
97
98    fn bytes(line: Self::Line) -> Self::Bytes {
99        line.into_bytes().into_iter()
100    }
101}
102
103impl<'a, B: BufRead> Input for &'a mut B {
104    type Lines = IoLines<Self>;
105    type Line = String;
106    type Bytes = IntoIter<u8>;
107
108    fn lines(self) -> Self::Lines {
109        BufRead::lines(self)
110    }
111
112    fn line(item: <Self::Lines as Iterator>::Item) -> Result<Self::Line, Error> {
113        item
114    }
115
116    fn bytes(line: Self::Line) -> Self::Bytes {
117        line.into_bytes().into_iter()
118    }
119}
120
121impl<B: BufRead> Input for IoLines<B> {
122    type Lines = Self;
123    type Line = String;
124    type Bytes = IntoIter<u8>;
125
126    fn lines(self) -> Self::Lines {
127        self
128    }
129
130    fn line(item: <Self::Lines as Iterator>::Item) -> Result<Self::Line, Error> {
131        item
132    }
133
134    fn bytes(line: Self::Line) -> Self::Bytes {
135        line.into_bytes().into_iter()
136    }
137}