1use std::{
2 fs::File,
3 io::{self, BufRead, BufReader},
4 path::Path,
5};
6
7use bincode::{config, decode_from_std_read};
8use itertools::Itertools;
9
10use crate::edge::{InputEdge, TrivialEdge};
11
12pub fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
15where
16 P: AsRef<Path>,
17{
18 let file = File::open(filename)?;
19 Ok(io::BufReader::new(file).lines())
20}
21
22pub fn read_graph_into_trivial_edges(filename: &str) -> Vec<TrivialEdge> {
23 let mut reader = BufReader::new(File::open(filename).unwrap());
24 let config = config::standard();
25
26 let input_edges: Vec<InputEdge<usize>> = decode_from_std_read(&mut reader, config).unwrap();
27
28 input_edges
29 .iter()
30 .map(|edge| TrivialEdge {
31 source: edge.source,
32 target: edge.target,
33 })
34 .collect_vec()
35}
36
37pub fn read_vec_from_file<T: bincode::Decode<()>>(filename: &str) -> Vec<T> {
38 let mut reader = BufReader::new(File::open(filename).unwrap());
39 let config = config::standard();
40 decode_from_std_read(&mut reader, config).unwrap()
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46 use std::io::Write;
47 use tempfile::NamedTempFile;
48
49 #[test]
51 fn test_read_lines() {
52 let mut file = NamedTempFile::new().unwrap();
54 writeln!(file, "line1").unwrap();
55 writeln!(file, "line2").unwrap();
56 writeln!(file, "line3").unwrap();
57
58 let lines = read_lines(file.path()).unwrap();
60 let lines: Vec<String> = lines.map(|line| line.unwrap()).collect();
61
62 assert_eq!(lines, vec!["line1", "line2", "line3"]);
64 }
65
66 #[test]
68 fn test_read_lines_nonexistent_file() {
69 let result = read_lines("nonexistent_file.txt");
70 assert!(result.is_err());
71 }
72
73 #[test]
75 fn test_read_graph_into_trivial_edges() {
76 #[derive(bincode::Encode)]
78 struct TestEdge {
79 source: usize,
80 target: usize,
81 weight: usize,
82 }
83
84 let input_edges = vec![
85 TestEdge {
86 source: 1,
87 target: 2,
88 weight: 10,
89 },
90 TestEdge {
91 source: 2,
92 target: 3,
93 weight: 20,
94 },
95 ];
96
97 let mut file = NamedTempFile::new().unwrap();
99 let config = config::standard();
100 bincode::encode_into_std_write(&input_edges, &mut file, config).unwrap();
101
102 let trivial_edges = read_graph_into_trivial_edges(file.path().to_str().unwrap());
104
105 assert_eq!(trivial_edges.len(), 2);
107 assert_eq!(trivial_edges[0].source, 1);
108 assert_eq!(trivial_edges[0].target, 2);
109 assert_eq!(trivial_edges[1].source, 2);
110 assert_eq!(trivial_edges[1].target, 3);
111 }
112
113 #[test]
115 #[should_panic]
116 fn test_read_graph_into_trivial_edges_nonexistent_file() {
117 read_graph_into_trivial_edges("nonexistent_file.bin");
118 }
119
120 #[test]
122 fn test_read_vec_from_file() {
123 let test_data = vec![1, 2, 3, 4, 5];
125
126 let mut file = NamedTempFile::new().unwrap();
128 let config = config::standard();
129 bincode::encode_into_std_write(&test_data, &mut file, config).unwrap();
130
131 let result: Vec<i32> = read_vec_from_file(file.path().to_str().unwrap());
133
134 assert_eq!(result, test_data);
136 }
137
138 #[test]
140 fn test_read_vec_from_file_with_custom_struct() {
141 #[derive(Debug, PartialEq, bincode::Encode, bincode::Decode)]
143 struct TestStruct {
144 id: u64,
145 name: String,
146 }
147
148 let test_data = vec![
149 TestStruct {
150 id: 1,
151 name: "Alice".to_string(),
152 },
153 TestStruct {
154 id: 2,
155 name: "Bob".to_string(),
156 },
157 ];
158
159 let mut file = NamedTempFile::new().unwrap();
161 let config = config::standard();
162 bincode::encode_into_std_write(&test_data, &mut file, config).unwrap();
163
164 let result: Vec<TestStruct> = read_vec_from_file(file.path().to_str().unwrap());
166
167 assert_eq!(result, test_data);
169 }
170
171 #[test]
173 #[should_panic]
174 fn test_read_vec_from_file_nonexistent_file() {
175 read_vec_from_file::<i32>("nonexistent_file.bin");
176 }
177
178 #[test]
180 #[should_panic]
181 fn test_read_vec_from_file_invalid_data() {
182 let mut file = NamedTempFile::new().unwrap();
184 file.write_all(b"invalid binary data").unwrap();
185
186 let _: Vec<i32> = read_vec_from_file(file.path().to_str().unwrap());
188 }
189}