1use std::{
2 fs::File,
3 io::{self, BufRead, BufReader},
4 path::Path,
5};
6
7use bincode::deserialize_from;
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 reader = BufReader::new(File::open(filename).unwrap());
24
25 let input_edges: Vec<InputEdge<usize>> = deserialize_from(reader).unwrap();
26 let edges = input_edges
27 .iter()
28 .map(|edge| TrivialEdge {
29 source: edge.source,
30 target: edge.target,
31 })
32 .collect_vec();
33
34 edges
35}
36
37pub fn read_vec_from_file<T: serde::de::DeserializeOwned>(filename: &str) -> Vec<T> {
38 let reader = BufReader::new(File::open(filename).unwrap());
39 deserialize_from(reader).unwrap()
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45 use serde::{Deserialize, Serialize};
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(Serialize)]
78 struct TestEdge {
79 source: usize,
80 target: usize,
81 weight: f64,
82 }
83
84 let input_edges = vec![
85 TestEdge {
86 source: 1,
87 target: 2,
88 weight: 1.0,
89 },
90 TestEdge {
91 source: 2,
92 target: 3,
93 weight: 2.0,
94 },
95 ];
96
97 let mut file = NamedTempFile::new().unwrap();
99 bincode::serialize_into(&mut file, &input_edges).unwrap();
100
101 let trivial_edges = read_graph_into_trivial_edges(file.path().to_str().unwrap());
103
104 assert_eq!(trivial_edges.len(), 2);
106 assert_eq!(trivial_edges[0].source, 1);
107 assert_eq!(trivial_edges[0].target, 2);
108 assert_eq!(trivial_edges[1].source, 2);
109 assert_eq!(trivial_edges[1].target, 3);
110 }
111
112 #[test]
114 #[should_panic]
115 fn test_read_graph_into_trivial_edges_nonexistent_file() {
116 read_graph_into_trivial_edges("nonexistent_file.bin");
117 }
118
119 #[test]
121 fn test_read_vec_from_file() {
122 let test_data = vec![1, 2, 3, 4, 5];
124
125 let mut file = NamedTempFile::new().unwrap();
127 bincode::serialize_into(&mut file, &test_data).unwrap();
128
129 let result: Vec<i32> = read_vec_from_file(file.path().to_str().unwrap());
131
132 assert_eq!(result, test_data);
134 }
135
136 #[test]
138 fn test_read_vec_from_file_with_custom_struct() {
139 #[derive(Serialize, Deserialize, Debug, PartialEq)]
141 struct TestStruct {
142 id: u64,
143 name: String,
144 }
145
146 let test_data = vec![
147 TestStruct {
148 id: 1,
149 name: "Alice".to_string(),
150 },
151 TestStruct {
152 id: 2,
153 name: "Bob".to_string(),
154 },
155 ];
156
157 let mut file = NamedTempFile::new().unwrap();
159 bincode::serialize_into(&mut file, &test_data).unwrap();
160
161 let result: Vec<TestStruct> = read_vec_from_file(file.path().to_str().unwrap());
163
164 assert_eq!(result, test_data);
166 }
167
168 #[test]
170 #[should_panic]
171 fn test_read_vec_from_file_nonexistent_file() {
172 read_vec_from_file::<i32>("nonexistent_file.bin");
173 }
174
175 #[test]
177 #[should_panic]
178 fn test_read_vec_from_file_invalid_data() {
179 let mut file = NamedTempFile::new().unwrap();
181 file.write_all(b"invalid binary data").unwrap();
182
183 let _: Vec<i32> = read_vec_from_file(file.path().to_str().unwrap());
185 }
186}