libmeld/
lib.rs

1use log::{error, info, warn};
2use sha2::{Digest, Sha512};
3use snafu::{self, Snafu};
4use std::{collections::HashMap, fs, path::PathBuf};
5
6mod bin;
7mod config;
8mod db;
9mod map;
10pub mod mapper;
11mod version;
12
13#[derive(Debug, Snafu)]
14pub enum Error {
15    // Init Related Errors
16    #[snafu(display("{bin} already exists"))]
17    BinAlreadyExists { bin: String },
18    #[snafu(display("bin's parent tree does not exist; -p"))]
19    ParentsDontExist,
20    #[snafu(display("Init Failed: {msg}"))]
21    InitFailed { msg: String },
22    // Bin Errors
23    #[snafu(display("Map Update Not Needed"))]
24    UpdateNotNeeded,
25    //SQL Errors
26    #[snafu(display("SQL Failed: {msg}"))]
27    SQLError { msg: String },
28    // General Errors
29    #[snafu(display("IO Error: {msg}"))]
30    IOError { msg: String },
31    #[snafu(display("File not found: {msg}"))]
32    FileNotFound { msg: String },
33    #[snafu(display("Tag Not Found: {msg}"))]
34    TagNotFound { msg: String },
35    #[snafu(display("Something unexpected happened"))]
36    SomethingFailed,
37}
38
39pub struct Database {
40    path: PathBuf,
41}
42
43pub struct Bin {
44    path: PathBuf,
45    maps: PathBuf,
46    blobs: PathBuf,
47    pub db: Database,
48}
49
50pub struct Config {
51    blob: String,
52    real_path: String,
53    pub subset: String,
54    pub family: String,
55    map_path: String,
56    tag: String,
57    hash: String,
58    pub versions: HashMap<String, Version>,
59}
60
61pub struct Version {
62    pub data_hash: String,
63    pub ver: u32,
64    pub tag: String,
65    pub owner: String,
66}
67
68pub struct Map {
69    pub blob: String,
70    pub ver: u32,
71    pub hash: String,
72    pub tag: String,
73    pub configs: Vec<Config>,
74}
75
76pub fn is_dir(path: &str) -> Result<bool, Error> {
77    match fs::metadata(path) {
78        Err(e) => {
79            error!("Could not get metadata for {}", path);
80            Err(Error::IOError { msg: e.to_string() })
81        }
82        Ok(md) => Ok(md.is_dir()),
83    }
84}
85
86pub fn exists(path: &String) -> bool {
87    return fs::metadata(path).is_ok();
88}
89
90// SHA512 of mapped file name
91pub fn hash_path(path: &str) -> String {
92    info!("Hashing mapped name: {}", path);
93    let mut hasher = Sha512::new();
94    hasher.update(path.as_bytes());
95    format!("{:x}", hasher.finalize())
96}
97
98// SHA512 hash of file contents
99pub fn hash_contents(path: &str) -> Result<String, Error> {
100    if is_dir(path)? {
101        warn!("not hashing {}. dir", path);
102        return Ok(String::from("DIR"));
103    }
104    let mut file = fs::File::open(path).unwrap();
105    let mut hasher = Sha512::new();
106    std::io::copy(&mut file, &mut hasher).unwrap();
107    Ok(format!("{:x}", hasher.finalize()))
108}