summaryrefslogtreecommitdiff
path: root/src/genmeta.rs
blob: d5b14a3ef2265ddc7598e1c21be7c701884851d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//! Backup generations metadata.

use crate::schema::{SchemaVersion, VersionComponent};
use serde::Serialize;
use std::collections::HashMap;

/// Metadata about the local generation.
#[derive(Debug, Serialize)]
pub struct GenerationMeta {
    schema_version: SchemaVersion,
    extras: HashMap<String, String>,
}

impl GenerationMeta {
    /// Create from a hash map.
    pub fn from(mut map: HashMap<String, String>) -> Result<Self, GenerationMetaError> {
        let major: VersionComponent = metaint(&mut map, "schema_version_major")?;
        let minor: VersionComponent = metaint(&mut map, "schema_version_minor")?;
        Ok(Self {
            schema_version: SchemaVersion::new(major, minor),
            extras: map,
        })
    }

    /// Return schema version of local generation.
    pub fn schema_version(&self) -> SchemaVersion {
        self.schema_version
    }

    /// Get a value corresponding to a key in the meta table.
    pub fn get(&self, key: &str) -> Option<&String> {
        self.extras.get(key)
    }
}

fn metastr(map: &mut HashMap<String, String>, key: &str) -> Result<String, GenerationMetaError> {
    if let Some(v) = map.remove(key) {
        Ok(v)
    } else {
        Err(GenerationMetaError::NoMetaKey(key.to_string()))
    }
}

fn metaint(map: &mut HashMap<String, String>, key: &str) -> Result<u32, GenerationMetaError> {
    let v = metastr(map, key)?;
    let v = v
        .parse()
        .map_err(|err| GenerationMetaError::BadMetaInteger(key.to_string(), err))?;
    Ok(v)
}

/// Possible errors from getting generation metadata.
#[derive(Debug, thiserror::Error)]
pub enum GenerationMetaError {
    /// Missing from from 'meta' table.
    #[error("Generation 'meta' table does not have a row {0}")]
    NoMetaKey(String),

    /// Bad data in 'meta' table.
    #[error("Generation 'meta' row {0} has badly formed integer: {1}")]
    BadMetaInteger(String, std::num::ParseIntError),
}