bread_cli/
lib.rs

1#![cfg_attr(feature = "benchmark", feature(test))]
2
3pub mod error;
4use error::*;
5
6pub mod byte_writer;
7use byte_writer::ByteWriter;
8
9pub mod ascii;
10pub mod base;
11pub mod binary;
12pub mod hexadecimal;
13pub mod raw;
14
15mod util;
16
17/// Converts byte input stream format to byte output stream format
18///
19/// Iterates on bytes in istream and [writes] them to ostream.
20///
21/// [writes]: crate::byte_writer::ByteWriter::write
22///
23/// # Errors
24///
25/// see [ErrorType] for error details.
26///
27/// [ErrorType]: crate::error::ErrorType
28///
29/// # Examples
30///
31/// binary to hexadecimal conversion
32/// ```
33/// use bread_cli::*;
34/// const _0: u8 = '0' as u8;
35/// const _1: u8 = '1' as u8;
36/// const _4: u8 = '4' as u8;
37/// const _5: u8 = '5' as u8;
38/// const _A: u8 = 'a' as u8;
39/// const _F: u8 = 'f' as u8;
40///
41/// let input = [ _0, _1, _0, _0, _1, _0, _1, _0, _0, _1, _0, _1, _1, _1, _1, _1, ];
42/// let mut output = [0u8; 4];
43/// let mut reader = binary::Reader::new(input.as_slice());
44/// let mut writer = hexadecimal::Writer::new(output.as_mut_slice());
45/// convert(&mut reader, &mut writer).unwrap();
46/// assert_eq!([_4, _A, _5, _F], output);
47/// ```
48///
49pub fn convert<I, O>(istream: &mut I, ostream: &mut O) -> Result<(), Error>
50where
51    I: Iterator<Item = Result<u8, InError>> + ?Sized,
52    O: ByteWriter + ?Sized,
53{
54    for input in istream {
55        match input {
56            Ok(input) => {
57                if let Err(out_error) = ostream.write(input) {
58                    return Err(Error::Out(out_error));
59                }
60            }
61            Err(in_error) => {
62                return Err(Error::In(in_error));
63            }
64        }
65    }
66    Ok(())
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72    use crate::util::literals::*;
73
74    #[test]
75    fn bin2bin() {
76        let input = [
77            _0, _1, _0, _0, _1, _0, _1, _0, _0, _1, _0, _1, _1, _1, _1, _1,
78        ];
79        let mut output = [0u8; 16];
80        let mut reader = binary::Reader::new(input.as_slice());
81        let mut writer = binary::Writer::new(output.as_mut_slice());
82        convert(&mut reader, &mut writer).unwrap();
83        assert_eq!(input, output);
84    }
85
86    #[test]
87    fn hex2hex() {
88        let input = [_A, _7, _B.to_ascii_uppercase(), _3];
89        let mut output = [0u8; 4];
90        let mut reader = hexadecimal::Reader::new(input.as_slice());
91        let mut writer = hexadecimal::Writer::new(output.as_mut_slice());
92        convert(&mut reader, &mut writer).unwrap();
93        assert_eq!(input.to_ascii_lowercase(), output);
94    }
95
96    #[test]
97    fn ascii2ascii() {
98        let input = [_A, _B, _STAR, _EXCL];
99        let mut output = [0u8; 4];
100        let mut reader = ascii::Reader::new(input.as_slice());
101        let mut writer = ascii::Writer::new(output.as_mut_slice());
102        convert(&mut reader, &mut writer).unwrap();
103        assert_eq!(input, output);
104    }
105
106    #[test]
107    fn raw2raw() {
108        let input = [10u8, 128u8, 255u8, 4u8];
109        let mut output = [0u8; 4];
110        let mut reader = raw::Reader::new(input.as_slice());
111        let mut writer = raw::Writer::new(output.as_mut_slice());
112        convert(&mut reader, &mut writer).unwrap();
113        assert_eq!(input, output);
114    }
115
116    #[test]
117    fn bin2hex() {
118        let input = [
119            _0, _1, _0, _0, _1, _0, _1, _0, _0, _1, _0, _1, _1, _1, _1, _1,
120        ];
121        let mut output = [0u8; 4];
122        let mut reader = binary::Reader::new(input.as_slice());
123        let mut writer = hexadecimal::Writer::new(output.as_mut_slice());
124        convert(&mut reader, &mut writer).unwrap();
125        assert_eq!([_4, _A, _5, _F], output);
126    }
127
128    #[test]
129    fn bin2ascii() {
130        let input = [
131            _0, _0, _1, _0, _1, _0, _1, _0, _0, _0, _1, _0, _0, _0, _0, _1,
132        ];
133        let expected = [_STAR, _EXCL];
134        let mut output = [0u8; 2];
135        let mut reader = binary::Reader::new(input.as_slice());
136        let mut writer = ascii::Writer::new(output.as_mut_slice());
137        convert(&mut reader, &mut writer).unwrap();
138        assert_eq!(expected, output);
139    }
140
141    #[test]
142    fn ascii2hex() {
143        let input = [_A, _B, _STAR, _EXCL];
144        let expected = [_6, _1, _6, _2, _2, _A, _2, _1];
145        let mut output = [0u8; 8];
146        let mut reader = ascii::Reader::new(input.as_slice());
147        let mut writer = hexadecimal::Writer::new(output.as_mut_slice());
148        convert(&mut reader, &mut writer).unwrap();
149        assert_eq!(expected, output);
150    }
151
152    #[test]
153    fn raw2hex() {
154        let input = [0xfa, 0x4b];
155        let expected = [_F, _A, _4, _B];
156        let mut output = [0u8; 4];
157        let mut reader = raw::Reader::new(input.as_slice());
158        let mut writer = hexadecimal::Writer::new(output.as_mut_slice());
159        convert(&mut reader, &mut writer).unwrap();
160        assert_eq!(expected, output);
161    }
162
163    #[test]
164    fn ascii2raw() {
165        let input = [_0, _A, _2, _EXCL, _STAR];
166        let mut output = [0u8; 5];
167        let mut reader = ascii::Reader::new(input.as_slice());
168        let mut writer = raw::Writer::new(output.as_mut_slice());
169        convert(&mut reader, &mut writer).unwrap();
170        assert_eq!(input, output);
171    }
172
173    #[test]
174    fn b16_hex() {
175        let input = [_1, _F];
176        let mut output = [0u8; 2];
177        let mut reader = base::Reader::new(input.as_slice(), 16);
178        let mut writer = hexadecimal::Writer::new(output.as_mut_slice());
179        convert(&mut reader, &mut writer).unwrap();
180        assert_eq!(input, output);
181    }
182
183    #[test]
184    fn b10_hex() {
185        let input = [_0, _1, _2];
186        let mut output = [0u8; 2];
187        let expected = [_0, _C];
188        let mut reader = base::Reader::new(input.as_slice(), 10);
189        let mut writer = hexadecimal::Writer::new(output.as_mut_slice());
190        convert(&mut reader, &mut writer).unwrap();
191        assert_eq!(expected, output);
192    }
193
194    #[test]
195    fn b10_to_b16() {
196        let input = [_0, _1, _6, _2, _5, _4];
197        let mut output = [0u8; 4];
198        let expected = [_1, _0, _F, _E];
199        let mut reader = base::Reader::new(input.as_slice(), 10);
200        let mut writer = base::Writer::new(output.as_mut_slice(), 16);
201        convert(&mut reader, &mut writer).unwrap();
202        assert_eq!(expected, output);
203    }
204}
205
206#[cfg(all(test, feature = "benchmark"))]
207mod dispatch {
208    extern crate test;
209    use super::*;
210
211    #[bench]
212    fn static_dispatch(b: &mut test::Bencher) {
213        const N: usize = 1024 * 1024;
214        static INPUT: [u8; N] = [b'0'; N];
215        b.iter(|| {
216            let mut output = [0u8; N];
217            let mut reader = binary::Reader::new(INPUT.as_slice());
218            let mut writer = binary::Writer::new(output.as_mut_slice());
219            convert(&mut reader, &mut writer).unwrap();
220            assert_eq!([b'0'; N], output);
221        });
222    }
223
224    #[bench]
225    fn dynamic_dyspatch(b: &mut test::Bencher) {
226        const N: usize = 1024 * 1024;
227        static INPUT: [u8; N] = [b'0'; N];
228        b.iter(|| {
229            let mut output = [0u8; N];
230            let mut reader = Box::new(binary::Reader::new(INPUT.as_slice()));
231            let mut writer = Box::new(binary::Writer::new(output.as_mut_slice()));
232            convert(reader.as_mut(), writer.as_mut()).unwrap();
233            assert_eq!([b'0'; N], output);
234        });
235    }
236}