use serde::{Deserialize, Serialize};
use std::{
env,
fs::{create_dir_all, read_to_string},
io::{self, Write},
path::PathBuf,
};
use tempfile::NamedTempFile;
use time::OffsetDateTime;
#[derive(Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct OpenOrder {
pub order_id: i32,
pub order_ref: String,
pub perm_id: Option<i64>,
#[serde(with = "time::serde::timestamp")]
pub created_at: OffsetDateTime,
}
#[derive(Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct State {
pub open_orders: Vec<OpenOrder>,
}
fn path() -> Option<PathBuf> {
dirs::data_local_dir()
.or_else(|| {
env::var("LOCALAPPDATA").ok().map(Into::into)
})
.map(|path| path.join("stockholm/state.yml"))
}
pub fn initial() -> State {
State {
open_orders: Vec::new(),
}
}
pub fn load() -> io::Result<State> {
if let Some(path) = path() {
let yaml = read_to_string(path)?;
yaml_serde::from_str(&yaml).map_err(io::Error::other)
} else {
Err(io::Error::other("Unable to locate data directory."))
}
}
pub fn save(state: &State) -> io::Result<()> {
if let Some(path) = path() {
let parent = path.parent().unwrap().to_owned();
let payload = yaml_serde::to_string(state).unwrap();
create_dir_all(parent.clone())?;
let mut temp_file = NamedTempFile::new_in(parent)?;
temp_file.write_all(payload.as_bytes())?;
temp_file.flush()?;
temp_file.persist(path)?;
} else {
return Err(io::Error::other("Unable to locate data directory."));
}
Ok(())
}