token_read/impls/
array.rs1use std::str::FromStr;
2
3use arrayvec::ArrayVec;
4
5use crate::{FromTokens, ParseTokenPatternError};
6
7impl<T, const N: usize> FromTokens for [T; N]
8where
9 T: FromStr,
10{
11 type Error = ParseTokenPatternError<T::Err>;
12
13 fn from_tokens<'a, I>(tokens: I) -> Result<Self, Self::Error>
14 where
15 I: Iterator<Item = &'a str>,
16 {
17 let mut array: ArrayVec<T, N> = ArrayVec::new();
18
19 for token in tokens.map(|v| v.parse()) {
20 let token = token.map_err(|source| ParseTokenPatternError::ParseError { source })?;
21
22 array
23 .try_push(token)
24 .map_err(|_| ParseTokenPatternError::TooManyTokens { expected: N })?;
25 }
26
27 array
28 .into_inner()
29 .map_err(|e| ParseTokenPatternError::TooFewTokens {
30 real: e.len(),
31 expected: N,
32 })
33 }
34}
35
36#[cfg(test)]
37mod tests {
38 use crate::{ParseTokenPatternError, ReadTokensError, TokenReader};
39
40 #[test]
41 fn reads_array() {
42 let mut input = TokenReader::new("10 11 12 13".as_bytes());
43 let value: [u8; 4] = input.line().unwrap();
44 assert_eq!(value, [10, 11, 12, 13]);
45 }
46
47 #[test]
48 fn returns_error_on_too_many_elements() {
49 let mut input = TokenReader::new("10 11 12 13 14".as_bytes());
50 let result = input.line::<[u8; 4]>();
51
52 assert!(matches!(
53 result,
54 Err(ReadTokensError::ParseError {
55 source: ParseTokenPatternError::TooManyTokens { expected: 4 },
56 ..
57 })
58 ));
59 }
60
61 #[test]
62 fn returns_error_on_too_few_elements() {
63 let mut input = TokenReader::new("10 11 12".as_bytes());
64 let result = input.line::<[u8; 4]>();
65
66 assert!(matches!(
67 result,
68 Err(ReadTokensError::ParseError {
69 source: ParseTokenPatternError::TooFewTokens {
70 expected: 4,
71 real: 3
72 },
73 ..
74 })
75 ));
76 }
77}