1
use std::path::PathBuf;
2

            
3
use clap::Subcommand;
4

            
5
use crate::{config::StorageConfiguration, Error, Storage};
6

            
7
/// Commands operating on local database storage.
8
150
#[derive(Subcommand, Debug)]
9
pub enum StorageCommand {
10
    /// Back up the storage.
11
    #[clap(subcommand)]
12
    Backup(Location),
13
    /// Restore the storage from backup.
14
    #[clap(subcommand)]
15
    Restore(Location),
16
}
17

            
18
/// A backup location.
19
400
#[derive(Subcommand, Debug)]
20
pub enum Location {
21
    /// A filesystem-based backup location.
22
    Path {
23
100
        /// The path to the backup directory.
24
50
        path: PathBuf,
25
    },
26
}
27

            
28
impl StorageCommand {
29
    /// Executes the command after opening a [`Storage`] instance using `config`.
30
    pub async fn execute(&self, config: StorageConfiguration) -> Result<(), Error> {
31
        let storage = Storage::open(config).await?;
32
        self.execute_on(&storage).await
33
    }
34

            
35
    /// Executes the command on `storage`.
36
50
    pub async fn execute_on(&self, storage: &Storage) -> Result<(), Error> {
37
2
        match self {
38
29
            StorageCommand::Backup(location) => location.backup(storage).await,
39
48
            StorageCommand::Restore(location) => location.restore(storage).await,
40
        }
41
2
    }
42
}
43

            
44
impl Location {
45
    /// Backs-up `storage` to `self`.
46
25
    pub async fn backup(&self, storage: &Storage) -> Result<(), Error> {
47
1
        match self {
48
29
            Location::Path { path } => storage.backup(path.as_path()).await,
49
        }
50
1
    }
51

            
52
    /// Restores `storage` from `self`.
53
25
    pub async fn restore(&self, storage: &Storage) -> Result<(), Error> {
54
1
        match self {
55
48
            Location::Path { path } => storage.restore(path.as_path()).await,
56
        }
57
1
    }
58
}