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
180
#[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
480
#[derive(Subcommand, Debug)]
20
pub enum Location {
21
    /// A filesystem-based backup location.
22
    Path {
23
120
        /// The path to the backup directory.
24
60
        path: PathBuf,
25
    },
26
}
27

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

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

            
43
    /// Executes the command on `storage`.
44
    #[cfg(feature = "async")]
45
60
    pub async fn execute_on_async(&self, storage: &crate::AsyncStorage) -> Result<(), Error> {
46
2
        match self {
47
1
            StorageCommand::Backup(location) => location.backup_async(storage).await,
48
1
            StorageCommand::Restore(location) => location.restore_async(storage).await,
49
        }
50
2
    }
51
}
52

            
53
impl Location {
54
    /// Backs-up `storage` to `self`.
55
    pub fn backup(&self, storage: &Storage) -> Result<(), Error> {
56
        match self {
57
            Location::Path { path } => storage.backup(path),
58
        }
59
    }
60

            
61
    /// Restores `storage` from `self`.
62
    pub fn restore(&self, storage: &Storage) -> Result<(), Error> {
63
        match self {
64
            Location::Path { path } => storage.restore(path),
65
        }
66
    }
67
    /// Backs-up `storage` to `self`.
68
    #[cfg(feature = "async")]
69
30
    pub async fn backup_async(&self, storage: &crate::AsyncStorage) -> Result<(), Error> {
70
1
        match self {
71
1
            Location::Path { path } => storage.backup(path.clone()).await,
72
        }
73
1
    }
74

            
75
    /// Restores `storage` from `self`.
76
    #[cfg(feature = "async")]
77
30
    pub async fn restore_async(&self, storage: &crate::AsyncStorage) -> Result<(), Error> {
78
1
        match self {
79
1
            Location::Path { path } => storage.restore(path.clone()).await,
80
        }
81
1
    }
82
}