1mod helpers;
6
7use std::any::TypeId;
8use std::fs::File;
9use std::io::{self, Read, Stdin};
10use std::str::FromStr;
11
12pub trait Import {
13 fn import<T: FromStr + 'static>(&self) -> io::Result<T>;
14}
15
16impl Import for Stdin {
17 fn import<T: FromStr + 'static>(&self) -> io::Result<T> {
19 let mut data = String::new();
20 let _ = self.read_line(&mut data)?;
21 data.trim().parse::<T>().map_err(|_| helpers::parse_error())
22 }
23}
24
25impl Import for File {
26 fn import<T: FromStr + 'static>(&self) -> io::Result<T> {
28 let mut data = Vec::<u8>::new();
29 let mut buf = [0_u8; 1];
30 loop {
31 let mut u_cell = std::cell::UnsafeCell::new(self);
32 let mut_self = u_cell.get_mut();
33
34 match mut_self.read_exact(&mut buf) {
35 Ok(_) => {
36 if TypeId::of::<T>() == TypeId::of::<String>() {
37 if buf[0] == b'\n' {
38 break;
39 };
40 } else {
41 if buf[0] == b' ' || buf[0] == b'\t' || buf[0] == b'\n' {
42 break;
43 };
44 }
45 data.push(buf[0]);
46 }
47 Err(e) => {
48 if e.kind() == io::ErrorKind::UnexpectedEof {
49 break;
50 } else {
51 return Err(e);
52 }
53 }
54 }
55 }
56 let data = String::from_utf8(data).map_err(|e| helpers::utf8_error(e))?;
57 data.trim().parse::<T>().map_err(|_| helpers::parse_error())
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn test_import_numbers() {
67 let f = File::open("tests/numbers.txt").unwrap();
68 {
69 let num = f.import::<i32>();
70 assert_eq!(num.unwrap_or_default(), 123);
71 }
72 {
73 let num = f.import::<u32>();
74 assert_eq!(num.unwrap_or_default(), 12);
75 }
76 {
77 let num = f.import::<i32>();
78 assert_eq!(num.unwrap_or_default(), -9);
79 }
80 {
81 let num = f.import::<f32>();
82 assert_eq!(num.unwrap_or_default(), 12.098);
83 }
84 {
85 let num = f.import::<f64>();
86 assert_eq!(num.unwrap_or_default(), -0.000001);
87 }
88 {
89 let num = f.import::<u64>();
90 assert_eq!(num.unwrap_or_default(), 0);
91 }
92 {
93 let num = f.import::<f64>();
94 assert_eq!(num.unwrap_or_default(), -0.);
95 }
96 {
97 let num = f.import::<f64>();
98 assert_eq!(num.unwrap_or_default(), 0.);
99 }
100 {
101 let num = f.import::<f32>();
102 assert_eq!(num.unwrap_or_default(), 1e-5);
103 }
104 }
105
106 #[test]
107 fn test_import_strings() {
108 let f = File::open("tests/strings.txt").unwrap();
109 {
110 let s = f.import::<String>();
111 assert_eq!(s.unwrap_or_default(), "aaa bbb");
112 }
113 {
114 let s = f.import::<String>();
115 assert_eq!(s.unwrap_or("*".to_owned()), "");
116 }
117 {
118 let s = f.import::<String>();
119 assert_eq!(s.unwrap_or_default(), "ccc");
120 }
121 let _ = f.import::<String>();
122 {
123 let s = f.import::<String>();
124 assert_eq!(s.unwrap_or_default(), "Привет !");
125 }
126 let _ = f.import::<String>();
127 {
128 let s = f.import::<String>();
129 assert_eq!(s.unwrap_or_default(), "小 休");
130 }
131 }
132
133 #[test]
134 fn test_import_other() {
135 let f = File::open("tests/other.txt").unwrap();
136 {
137 let b = f.import::<bool>();
138 assert_eq!(b.unwrap_or_default(), true);
139 }
140 {
141 let b = f.import::<bool>();
142 assert_eq!(b.unwrap_or_default(), false);
143 }
144 {
145 let mut chars = Vec::<char>::new();
146 chars.push(f.import::<char>().unwrap());
147 chars.push(f.import::<char>().unwrap());
148 chars.push(f.import::<char>().unwrap());
149 assert_eq!(chars, vec!['a','m','d']);
150 }
151 {
152 let ch = f.import::<char>();
153 assert_eq!(ch.unwrap_or_default(), 'ё');
154 }
155 }
156}