1use chrono::{DateTime, Utc};
6use serde_derive::{Deserialize, Serialize};
7use std::{collections::BTreeMap, io::Write};
8
9use crate::{Error, Result};
10
11#[derive(Clone, Serialize, Deserialize)]
15pub struct Header {
16 pub version: usize,
17 pub deltas: Vec<DeltaInfo>,
18}
19
20#[derive(Clone, Serialize, Deserialize)]
22pub struct DeltaInfo {
23 pub name: String,
25 pub number: usize,
27 pub tags: BTreeMap<String, String>,
29 pub time: DateTime<Utc>,
31}
32
33const THIS_VERSION: usize = 1;
34
35impl Default for Header {
36 fn default() -> Header {
37 Header {
38 version: THIS_VERSION,
39 deltas: vec![],
40 }
41 }
42}
43
44impl Header {
45 pub fn decode(line: &str) -> Result<Header> {
47 if let Some(rest) = line.strip_prefix("\x01t") {
48 Ok(serde_json::from_str(rest)?)
49 } else {
50 Ok(Header {
52 version: 0,
53 deltas: vec![],
54 })
55 }
56 }
57
58 pub fn add(&mut self, mut tags: BTreeMap<String, String>) -> Result<usize> {
60 let name = if let Some(name) = tags.remove("name") {
61 name
62 } else {
63 return Err(Error::NameMissing);
64 };
65
66 let next_delta = self.deltas.iter().map(|x| x.number).max().unwrap_or(0) + 1;
67
68 self.deltas.push(DeltaInfo {
69 name,
70 number: next_delta,
71 tags,
72 time: Utc::now(),
73 });
74
75 Ok(next_delta)
76 }
77
78 pub fn write<W: Write>(&self, mut wr: &mut W) -> Result<()> {
80 write!(&mut wr, "\x01t")?;
81 serde_json::to_writer(&mut wr, &self)?;
82 writeln!(&mut wr)?;
83 Ok(())
84 }
85}