argmin/core/observers/
file.rsuse crate::core::{ArgminKV, ArgminOp, Error, IterState, Observe};
use serde::{Deserialize, Serialize};
use std::default::Default;
use std::fs::File;
use std::io::BufWriter;
use std::path::Path;
#[derive(Copy, Clone, Serialize, Deserialize, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum WriteToFileSerializer {
Bincode,
JSON,
}
impl Default for WriteToFileSerializer {
fn default() -> Self {
WriteToFileSerializer::Bincode
}
}
#[derive(Clone, Serialize, Deserialize, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct WriteToFile<O> {
dir: String,
prefix: String,
serializer: WriteToFileSerializer,
_param: std::marker::PhantomData<O>,
}
impl<O: ArgminOp> WriteToFile<O> {
pub fn new(dir: &str, prefix: &str) -> Self {
WriteToFile {
dir: dir.to_string(),
prefix: prefix.to_string(),
serializer: WriteToFileSerializer::Bincode,
_param: std::marker::PhantomData,
}
}
pub fn serializer(mut self, serializer: WriteToFileSerializer) -> Self {
self.serializer = serializer;
self
}
}
impl<O: ArgminOp> Observe<O> for WriteToFile<O> {
fn observe_iter(&mut self, state: &IterState<O>, _kv: &ArgminKV) -> Result<(), Error> {
let param = state.get_param();
let iter = state.get_iter();
let dir = Path::new(&self.dir);
if !dir.exists() {
std::fs::create_dir_all(&dir)?
}
let mut fname = self.prefix.clone();
fname.push_str("_");
fname.push_str(&iter.to_string());
fname.push_str(".arp");
let fname = dir.join(fname);
let f = BufWriter::new(File::create(fname)?);
match self.serializer {
WriteToFileSerializer::Bincode => {
bincode::serialize_into(f, ¶m)?;
}
WriteToFileSerializer::JSON => {
serde_json::to_writer_pretty(f, ¶m)?;
}
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
send_sync_test!(write_to_file, WriteToFile<Vec<f64>>);
}