libmeld/
bin.rs

1use log::info;
2use log::warn;
3
4use crate::Bin;
5use crate::Database;
6use crate::Error;
7
8use std::{fs::DirBuilder, path::PathBuf};
9
10const MAP_DIR: &str = "maps";
11const BLOBS_DIR: &str = "blobs";
12const MELD_DB: &str = "meld.db";
13
14impl Bin {
15    // Getters
16    pub fn get_maps_str(&self) -> Result<String, Error> {
17        match self.maps.to_str() {
18            Some(s) => Ok(s.to_string()),
19            None => Err(Error::IOError {
20                msg: "Failed to get maps".to_string(),
21            }),
22        }
23    }
24
25    pub fn get_blobs_str(&self) -> Result<String, Error> {
26        match self.blobs.to_str() {
27            Some(s) => Ok(s.to_string()),
28            None => Err(Error::IOError {
29                msg: "Failed to get maps".to_string(),
30            }),
31        }
32    }
33
34    fn is_valid(&self) -> bool {
35        return self.path.exists()
36            && self.blobs.exists()
37            && self.maps.exists()
38            && self.db.path.exists()
39            && self.db.is_valid();
40    }
41
42    /// Parse a Meld Bin from a Path
43    pub fn from(path: String) -> Result<Self, Error> {
44        info!("Opening bin at {}", path);
45        let bin = Bin {
46            path: PathBuf::from(&path),
47            maps: PathBuf::from(format!("{}/{}", &path, MAP_DIR)),
48            blobs: PathBuf::from(format!("{}/{}", &path, BLOBS_DIR)),
49            db: Database {
50                path: PathBuf::from(format!("{}/{}", &path, MELD_DB)),
51            },
52        };
53
54        // sanity check creation
55        return if bin.is_valid() {
56            Ok(bin)
57        } else {
58            Err(Error::InitFailed {
59                msg: "Selected bin is invalid".to_string(),
60            })
61        };
62    }
63
64    // Helper function for repeated dir creation
65    fn create_dir(dirb: &DirBuilder, path: &PathBuf) -> Result<(), Error> {
66        info!("Creating {:?}", path);
67        match dirb.create(path) {
68            Ok(_) => Ok(()),
69            Err(e) => {
70                if e.kind() == std::io::ErrorKind::NotFound {
71                    return Err(Error::ParentsDontExist);
72                } else {
73                    return Err(Error::InitFailed {
74                        msg: "Failed to Create Valid Bin".to_string(),
75                    });
76                }
77            }
78        }
79    }
80
81    /// Create and init a new Meld Bin
82    pub fn new(path: String, force: bool, parents: bool) -> Result<Self, Error> {
83        info!("Creating bin at {}", path);
84        let bin = Bin {
85            path: PathBuf::from(&path),
86            maps: PathBuf::from(format!("{}/{}", &path, MAP_DIR)),
87            blobs: PathBuf::from(format!("{}/{}", &path, BLOBS_DIR)),
88            db: Database {
89                path: PathBuf::from(format!("{}/{}", &path, MELD_DB)),
90            },
91        };
92
93        // Create dirbuilder and set options
94        let mut dirb = DirBuilder::new();
95        dirb.recursive(parents);
96        if bin.path.exists() {
97            warn!("Bin folder already exists");
98            if !force {
99                return Err(Error::BinAlreadyExists { bin: path });
100            } else {
101                warn!("Removing {}", path);
102                match std::fs::remove_dir_all(path) {
103                    Ok(_) => {}
104                    Err(e) => return Err(Error::InitFailed { msg: e.to_string() }),
105                }
106            }
107        }
108
109        // create all needed folders
110        Bin::create_dir(&dirb, &bin.path)?;
111        Bin::create_dir(&dirb, &bin.maps)?;
112        Bin::create_dir(&dirb, &bin.blobs)?;
113
114        // create and initialize SQLite table
115        bin.db.create_db_schema()?;
116
117        // sanity check creation
118        return if bin.is_valid() {
119            Ok(bin)
120        } else {
121            Err(Error::InitFailed {
122                msg: "Failed to Create Valid Bin".to_string(),
123            })
124        };
125    }
126}