use std::{
fs::File,
io::{self, BufRead, BufReader},
path::Path,
};
use bincode::{config, decode_from_std_read};
use itertools::Itertools;
use crate::edge::{InputEdge, TrivialEdge};
pub fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
where
P: AsRef<Path>,
{
let file = File::open(filename)?;
Ok(io::BufReader::new(file).lines())
}
pub fn read_graph_into_trivial_edges(filename: &str) -> Vec<TrivialEdge> {
let mut reader = BufReader::new(File::open(filename).unwrap());
let config = config::standard();
let input_edges: Vec<InputEdge<usize>> = decode_from_std_read(&mut reader, config).unwrap();
input_edges
.iter()
.map(|edge| TrivialEdge {
source: edge.source,
target: edge.target,
})
.collect_vec()
}
pub fn read_vec_from_file<T: bincode::Decode<()>>(filename: &str) -> Vec<T> {
let mut reader = BufReader::new(File::open(filename).unwrap());
let config = config::standard();
decode_from_std_read(&mut reader, config).unwrap()
}
#[cfg(test)]
mod tests {
use super::*;
use std::io::Write;
use tempfile::NamedTempFile;
#[test]
fn test_read_lines() {
let mut file = NamedTempFile::new().unwrap();
writeln!(file, "line1").unwrap();
writeln!(file, "line2").unwrap();
writeln!(file, "line3").unwrap();
let lines = read_lines(file.path()).unwrap();
let lines: Vec<String> = lines.map(|line| line.unwrap()).collect();
assert_eq!(lines, vec!["line1", "line2", "line3"]);
}
#[test]
fn test_read_lines_nonexistent_file() {
let result = read_lines("nonexistent_file.txt");
assert!(result.is_err());
}
#[test]
fn test_read_graph_into_trivial_edges() {
#[derive(bincode::Encode)]
struct TestEdge {
source: usize,
target: usize,
weight: usize,
}
let input_edges = vec![
TestEdge {
source: 1,
target: 2,
weight: 10,
},
TestEdge {
source: 2,
target: 3,
weight: 20,
},
];
let mut file = NamedTempFile::new().unwrap();
let config = config::standard();
bincode::encode_into_std_write(&input_edges, &mut file, config).unwrap();
let trivial_edges = read_graph_into_trivial_edges(file.path().to_str().unwrap());
assert_eq!(trivial_edges.len(), 2);
assert_eq!(trivial_edges[0].source, 1);
assert_eq!(trivial_edges[0].target, 2);
assert_eq!(trivial_edges[1].source, 2);
assert_eq!(trivial_edges[1].target, 3);
}
#[test]
#[should_panic]
fn test_read_graph_into_trivial_edges_nonexistent_file() {
read_graph_into_trivial_edges("nonexistent_file.bin");
}
#[test]
fn test_read_vec_from_file() {
let test_data = vec![1, 2, 3, 4, 5];
let mut file = NamedTempFile::new().unwrap();
let config = config::standard();
bincode::encode_into_std_write(&test_data, &mut file, config).unwrap();
let result: Vec<i32> = read_vec_from_file(file.path().to_str().unwrap());
assert_eq!(result, test_data);
}
#[test]
fn test_read_vec_from_file_with_custom_struct() {
#[derive(Debug, PartialEq, bincode::Encode, bincode::Decode)]
struct TestStruct {
id: u64,
name: String,
}
let test_data = vec![
TestStruct {
id: 1,
name: "Alice".to_string(),
},
TestStruct {
id: 2,
name: "Bob".to_string(),
},
];
let mut file = NamedTempFile::new().unwrap();
let config = config::standard();
bincode::encode_into_std_write(&test_data, &mut file, config).unwrap();
let result: Vec<TestStruct> = read_vec_from_file(file.path().to_str().unwrap());
assert_eq!(result, test_data);
}
#[test]
#[should_panic]
fn test_read_vec_from_file_nonexistent_file() {
read_vec_from_file::<i32>("nonexistent_file.bin");
}
#[test]
#[should_panic]
fn test_read_vec_from_file_invalid_data() {
let mut file = NamedTempFile::new().unwrap();
file.write_all(b"invalid binary data").unwrap();
let _: Vec<i32> = read_vec_from_file(file.path().to_str().unwrap());
}
}