use crate::StrError;
use serde::{Deserialize, Serialize};
use std::ffi::OsStr;
use std::fs::{self, File};
use std::io::BufReader;
use std::path::Path;
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct InputDataTetMesh {
pub points: Vec<(i32, f64, f64, f64)>,
pub facets: Vec<(i32, Vec<usize>)>,
pub holes: Vec<(f64, f64, f64)>,
pub regions: Vec<(i32, f64, f64, f64, Option<f64>)>,
}
impl InputDataTetMesh {
pub fn read_json<P>(full_path: &P) -> Result<Self, StrError>
where
P: AsRef<OsStr> + ?Sized,
{
let path = Path::new(full_path).to_path_buf();
let input = File::open(path).map_err(|_| "cannot open file")?;
let buffered = BufReader::new(input);
let mesh = serde_json::from_reader(buffered).map_err(|_| "cannot parse JSON file")?;
Ok(mesh)
}
pub fn write_json<P>(&self, full_path: &P) -> Result<(), StrError>
where
P: AsRef<OsStr> + ?Sized,
{
let path = Path::new(full_path).to_path_buf();
if let Some(p) = path.parent() {
fs::create_dir_all(p).map_err(|_| "cannot create directory")?;
}
let mut file = File::create(&path).map_err(|_| "cannot create file")?;
serde_json::to_writer(&mut file, &self).map_err(|_| "cannot write file")?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::InputDataTetMesh;
#[test]
fn read_and_write_tet_capture_errors() {
assert_eq!(
InputDataTetMesh::read_json("/tmp/not_found").err(),
Some("cannot open file")
);
assert_eq!(
InputDataTetMesh::read_json("./data/input/wrong_input_tetgen.json").err(),
Some("cannot parse JSON file")
);
let data = InputDataTetMesh {
points: vec![],
facets: vec![],
holes: vec![],
regions: vec![],
};
assert_eq!(data.write_json("/tmp/").err(), Some("cannot create file"));
}
#[test]
fn read_and_write_tet_json_work() {
let data = InputDataTetMesh {
points: vec![
(0, 0.0, 1.0, 0.0),
(0, 0.0, 0.0, 0.0),
(0, 1.0, 1.0, 0.0),
(0, 0.0, 1.0, 1.0),
],
facets: vec![
(0, vec![0, 2, 1]),
(0, vec![0, 1, 3]),
(0, vec![0, 3, 2]),
(0, vec![1, 2, 3]),
],
holes: vec![],
regions: vec![(1, 0.1, 0.9, 0.1, None)],
};
data.write_json("/tmp/tritet/test_read_and_write_tet_work.json")
.unwrap();
let data_read = InputDataTetMesh::read_json("/tmp/tritet/test_read_and_write_tet_work.json").unwrap();
assert_eq!(data.points, data_read.points);
assert_eq!(data.facets, data_read.facets);
assert_eq!(data.holes, data_read.holes);
assert_eq!(data.regions, data_read.regions);
}
}