56 lines
1.9 KiB
Rust
56 lines
1.9 KiB
Rust
use std::fs::{create_dir_all, File};
|
|
use std::path::Path;
|
|
use rand::Rng;
|
|
use crate::cli::cli::OutputFormat;
|
|
use crate::system::model::DLASystem;
|
|
use crate::system::{Position, Storage};
|
|
use crate::system::spawner::Spawner;
|
|
use crate::system::sticker::Sticker;
|
|
use crate::system::walker::Walker;
|
|
|
|
pub fn write<R: Rng, P: Position, S: Storage<P>, W: Walker<P>, Sp: Spawner<P>, St: Sticker<P, S>>(
|
|
sys: &DLASystem<R, P, S, W, Sp, St>,
|
|
format: OutputFormat,
|
|
output: &Path,
|
|
) {
|
|
// If the parent does not exist (and we are not in the root or operating a relative 1-component-length path))
|
|
// create it. This greatly simplifies the harness code.
|
|
if let Some(parent) = output.parent() &&
|
|
parent.to_str().map(|x| x != "").unwrap_or(true) &&
|
|
!parent.exists() {
|
|
create_dir_all(parent).expect("Failed to create path to output");
|
|
}
|
|
|
|
match format {
|
|
OutputFormat::FullDataJson => write_json_full_data(sys, output),
|
|
OutputFormat::Positions => write_csv_positions(sys, output),
|
|
}
|
|
}
|
|
|
|
fn write_csv_positions<R: Rng, P: Position, S: Storage<P>, W: Walker<P>, Sp: Spawner<P>, St: Sticker<P, S>>(sys: &DLASystem<R, P, S, W, Sp, St>, csv_path: &Path) {
|
|
let mut wtr = csv::Writer::from_path(csv_path)
|
|
.expect("Failed to open file");
|
|
|
|
// CSVs can only store the raw positions
|
|
let positions: Vec<&P> = sys.history
|
|
.iter()
|
|
.map(|line| &line.position)
|
|
.collect();
|
|
|
|
positions
|
|
.iter()
|
|
.for_each(|position|
|
|
wtr.serialize(position).expect("Failed to write row")
|
|
);
|
|
|
|
wtr.flush()
|
|
.unwrap();
|
|
}
|
|
|
|
fn write_json_full_data<R: Rng, P: Position, S: Storage<P>, W: Walker<P>, Sp: Spawner<P>, St: Sticker<P, S>>(sys: &DLASystem<R, P, S, W, Sp, St>, output_path: &Path) {
|
|
let file = File::create(output_path).expect("Failed to open file");
|
|
|
|
serde_json::to_writer_pretty(file, &sys.history)
|
|
.expect("Failed to write json");
|
|
}
|