1pub trait ParseGridExt {
2 fn to_2d_chars(&self) -> Vec<Vec<char>>;
3 fn to_2d_bytes(&self) -> Vec<Vec<u8>>;
4}
5
6impl ParseGridExt for str {
7 fn to_2d_chars(&self) -> Vec<Vec<char>> {
8 self.lines().map(|line| line.chars().collect()).collect()
9 }
10 fn to_2d_bytes(&self) -> Vec<Vec<u8>> {
11 self.lines().map(|line| line.bytes().collect()).collect()
12 }
13}
14
15pub trait StrParseExt {
16 fn int(&self) -> i32;
17 fn ints(&self) -> Vec<i32>;
18}
19
20impl StrParseExt for str {
21 fn int(&self) -> i32 {
22 self.to_string()
23 .trim()
24 .parse()
25 .unwrap_or_else(|_| panic!("tried to parse {} as int", self))
26 }
27
28 fn ints(&self) -> Vec<i32> {
29 self.to_string()
30 .split(|c: char| !c.is_numeric() && c != '-')
31 .filter_map(|x| {
32 if x.is_empty() {
33 None
34 } else {
35 Some(x.trim().int())
36 }
37 })
38 .collect()
39 }
40}
41
42pub fn to_ints(s: &[char]) -> Vec<i32> {
43 let string = s.iter().collect::<String>();
44 string
45 .split(|c: char| !c.is_numeric() && c != '-')
46 .filter_map(|x| {
47 if x.is_empty() {
48 None
49 } else {
50 Some(x.trim().int())
51 }
52 })
53 .collect()
54}
55
56pub fn to_uints(s: &[char]) -> Vec<u32> {
57 let string = s.iter().collect::<String>();
58 string
59 .split(|c: char| !c.is_numeric())
60 .filter_map(|x| {
61 if x.is_empty() {
62 None
63 } else {
64 Some(x.trim().int() as u32)
65 }
66 })
67 .collect()
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use crate::{ParseGridExt, StrParseExt};
74
75 #[test]
76 fn test_parse_grid() {
77 assert_eq!(
78 "Hello\nWorld".to_2d_chars(),
79 vec![vec!['H', 'e', 'l', 'l', 'o'], vec!['W', 'o', 'r', 'l', 'd']]
80 );
81 assert_eq!(
82 "Hello\nWorld".to_2d_bytes(),
83 vec![
84 vec![b'H', b'e', b'l', b'l', b'o'],
85 vec![b'W', b'o', b'r', b'l', b'd']
86 ]
87 );
88 }
89
90 #[test]
91 fn test_str_int() {
92 assert_eq!("42".int(), 42);
93 assert_eq!(" 42 ".int(), 42);
94 assert_eq!(" -42 ".int(), -42);
95 }
96
97 #[test]
98 fn test_str_ints() {
99 assert_eq!("1 2 3 4".ints(), vec![1, 2, 3, 4]);
100 assert_eq!("1 a2b3asdf4 asd".ints(), vec![1, 2, 3, 4]);
101 assert_eq!("1 -12a-33 4".ints(), vec![1, -12, -33, 4]);
102 assert_eq!("".ints(), vec![]);
103 }
104
105 #[test]
106 fn test_to_ints() {
107 assert_eq!(to_ints(&['4', '2']), vec![42]);
108 assert_eq!(to_ints(&['4', '2', 'a', ' ', '1']), vec![42, 1]);
109 assert_eq!(to_ints(&['a', '-', '4', '2']), vec![-42]);
110 assert_eq!(to_ints(&['a']), vec![]);
111 }
112}