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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
use crate::fs_utils::*;
use crate::Result;
use serde::{de::DeserializeOwned, Serialize};
use std::marker::PhantomData;
use std::path::{Path, PathBuf};

pub struct DoubleBucket<V> {
    dir: PathBuf,
    max_file_name: Option<usize>,
    _v: PhantomData<V>,
}

/// DoubleBucket stores things one level deeper
impl<V: Serialize + DeserializeOwned> DoubleBucket<V> {
    pub(crate) fn new(dir: PathBuf, max_file_name: Option<usize>) -> Self {
        Self {
            dir,
            max_file_name: max_file_name,
            _v: PhantomData,
        }
    }
    /// dir of this bucket
    pub fn dir(&self) -> String {
        self.dir.to_string_lossy().to_string()
    }
    /// Check if a key exists within sub-bucket
    pub fn exists(&self, sub: &str, key: &str) -> bool {
        let mut path = self.dir.clone();
        path.push(self.maxify(sub));
        path.push(self.maxify(key));
        path.exists()
    }
    /// Create a key in a sub-bucket
    pub fn put(&self, sub: &str, key: &str, value: V) -> Result<()> {
        let mut path = self.dir.clone();
        path.push(self.maxify(sub));
        if !Path::new(&path).exists() {
            std::fs::create_dir(path.clone())?;
        }
        path.push(self.maxify(key));
        fs_put(path, value)
    }
    /// Get a key in a sub-bucket
    pub fn get(&self, sub: &str, key: &str) -> Result<V> {
        let mut path = self.dir.clone();
        path.push(self.maxify(sub));
        path.push(self.maxify(key));
        fs_get(path)
    }
    /// Delete a file in a sub-bucket
    pub fn remove(&self, sub: &str, key: &str) -> Result<()> {
        let mut path = self.dir.clone();
        path.push(self.maxify(sub));
        path.push(self.maxify(key));
        fs_remove(path)
    }
    /// List keys in this bucket's sub-bucket
    pub fn list(&self, sub: &str) -> Result<Vec<String>> {
        let mut path = self.dir.clone();
        path.push(self.maxify(sub));
        fs_list(path)
    }
    /// Clear all keys in this sub-bucket
    pub fn clear(&self, sub: &str) -> Result<()> {
        let mut path = self.dir.clone();
        path.push(self.maxify(sub));
        fs_clear(path)
    }
    /// Clear all keys in the bucket
    pub fn clear_all(&self) -> Result<()> {
        let path = self.dir.clone();
        fs_clear(path)
    }
    fn maxify(&self, name: &str) -> String {
        maxify(name, self.max_file_name)
    }
}