buildchain/
manifest.rs

1// SPDX-License-Identifier: GPL-3.0-only
2
3use serde::{Deserialize, Serialize};
4use std::collections::BTreeMap;
5use std::fs::{read_dir, File};
6use std::io::{Error, ErrorKind, Result};
7use std::path::Path;
8
9use crate::Sha384;
10
11/// A manifest of build artifacts
12#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
13pub struct Manifest {
14    /// The timestamp of the source control revision
15    pub time: u64,
16    /// A dictionary of filenames and their hashes
17    pub files: BTreeMap<String, String>,
18}
19
20impl Manifest {
21    /// Create a new Manifest by reading the provided build directory
22    ///
23    /// # Arguments
24    ///
25    /// * `time` - the timestamp of the source control revision that was built
26    /// * `path` - the directory containing the build artifacts
27    ///
28    /// # Return
29    ///
30    /// The Manifest of the provided build data
31    ///
32    /// # Errors
33    ///
34    /// Errors that are encountered while reading will be returned
35    pub fn new<P: AsRef<Path>>(time: u64, path: P) -> Result<Manifest> {
36        let mut files = BTreeMap::new();
37
38        for entry_res in read_dir(path.as_ref())? {
39            let entry = entry_res?;
40
41            let name = entry
42                .file_name()
43                .into_string()
44                .map_err(|_| Error::new(ErrorKind::InvalidData, "Filename is not UTF-8"))?;
45
46            let file = File::open(entry.path())?;
47            let sha = Sha384::new(file)?;
48
49            files.insert(name, sha.to_base32());
50        }
51
52        Ok(Manifest { time, files })
53    }
54}