use chrono::{DateTime, Utc};
use serde_derive::{Deserialize, Serialize};
use std::{collections::BTreeMap, io::Write};
use crate::{Error, Result};
#[derive(Clone, Serialize, Deserialize)]
pub struct Header {
pub version: usize,
pub deltas: Vec<DeltaInfo>,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct DeltaInfo {
pub name: String,
pub number: usize,
pub tags: BTreeMap<String, String>,
pub time: DateTime<Utc>,
}
const THIS_VERSION: usize = 1;
impl Default for Header {
fn default() -> Header {
Header {
version: THIS_VERSION,
deltas: vec![],
}
}
}
impl Header {
pub fn decode(line: &str) -> Result<Header> {
if let Some(rest) = line.strip_prefix("\x01t") {
Ok(serde_json::from_str(rest)?)
} else {
Ok(Header {
version: 0,
deltas: vec![],
})
}
}
pub fn add(&mut self, mut tags: BTreeMap<String, String>) -> Result<usize> {
let name = if let Some(name) = tags.remove("name") {
name
} else {
return Err(Error::NameMissing);
};
let next_delta = self.deltas.iter().map(|x| x.number).max().unwrap_or(0) + 1;
self.deltas.push(DeltaInfo {
name,
number: next_delta,
tags,
time: Utc::now(),
});
Ok(next_delta)
}
pub fn write<W: Write>(&self, mut wr: &mut W) -> Result<()> {
write!(&mut wr, "\x01t")?;
serde_json::to_writer(&mut wr, &self)?;
writeln!(&mut wr)?;
Ok(())
}
}