1use crate::error::{ProblemError, Result};
7use serde::{de::DeserializeOwned, Serialize};
8use std::fs::File;
9use std::io::{BufReader, BufWriter, Read, Write};
10use std::path::Path;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum FileFormat {
15 Json,
17 JsonCompact,
19}
20
21impl FileFormat {
22 pub fn from_extension(path: &Path) -> Option<Self> {
24 let ext = path.extension()?.to_str()?.to_lowercase();
25 match ext.as_str() {
26 "json" => Some(FileFormat::Json),
27 _ => None,
28 }
29 }
30}
31
32pub fn write_problem<T: Serialize, P: AsRef<Path>>(
51 problem: &T,
52 path: P,
53 format: FileFormat,
54) -> Result<()> {
55 let file = File::create(path.as_ref())
56 .map_err(|e| ProblemError::IoError(format!("Failed to create file: {}", e)))?;
57 let writer = BufWriter::new(file);
58
59 match format {
60 FileFormat::Json => serde_json::to_writer_pretty(writer, problem)
61 .map_err(|e| ProblemError::SerializationError(format!("Failed to write JSON: {}", e))),
62 FileFormat::JsonCompact => serde_json::to_writer(writer, problem)
63 .map_err(|e| ProblemError::SerializationError(format!("Failed to write JSON: {}", e))),
64 }
65}
66
67pub fn read_problem<T: DeserializeOwned, P: AsRef<Path>>(path: P, format: FileFormat) -> Result<T> {
84 let file = File::open(path.as_ref())
85 .map_err(|e| ProblemError::IoError(format!("Failed to open file: {}", e)))?;
86 let reader = BufReader::new(file);
87
88 match format {
89 FileFormat::Json | FileFormat::JsonCompact => serde_json::from_reader(reader)
90 .map_err(|e| ProblemError::SerializationError(format!("Failed to parse JSON: {}", e))),
91 }
92}
93
94pub fn to_json<T: Serialize>(problem: &T) -> Result<String> {
96 serde_json::to_string_pretty(problem)
97 .map_err(|e| ProblemError::SerializationError(format!("Failed to serialize: {}", e)))
98}
99
100pub fn to_json_compact<T: Serialize>(problem: &T) -> Result<String> {
102 serde_json::to_string(problem)
103 .map_err(|e| ProblemError::SerializationError(format!("Failed to serialize: {}", e)))
104}
105
106pub fn from_json<T: DeserializeOwned>(json: &str) -> Result<T> {
108 serde_json::from_str(json)
109 .map_err(|e| ProblemError::SerializationError(format!("Failed to parse JSON: {}", e)))
110}
111
112pub fn read_file<P: AsRef<Path>>(path: P) -> Result<String> {
114 let mut file = File::open(path.as_ref())
115 .map_err(|e| ProblemError::IoError(format!("Failed to open file: {}", e)))?;
116 let mut contents = String::new();
117 file.read_to_string(&mut contents)
118 .map_err(|e| ProblemError::IoError(format!("Failed to read file: {}", e)))?;
119 Ok(contents)
120}
121
122pub fn write_file<P: AsRef<Path>>(path: P, contents: &str) -> Result<()> {
124 let mut file = File::create(path.as_ref())
125 .map_err(|e| ProblemError::IoError(format!("Failed to create file: {}", e)))?;
126 file.write_all(contents.as_bytes())
127 .map_err(|e| ProblemError::IoError(format!("Failed to write file: {}", e)))?;
128 Ok(())
129}
130
131#[cfg(test)]
132#[path = "unit_tests/io.rs"]
133mod tests;