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 #[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 #[snafu(display("Map Update Not Needed"))]
24 UpdateNotNeeded,
25 #[snafu(display("SQL Failed: {msg}"))]
27 SQLError { msg: String },
28 #[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
90pub 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
98pub 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}