rustic_rs/commands/
list.rs

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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//! `list` subcommand

use std::num::NonZero;

use crate::{repository::CliOpenRepo, status_err, Application, RUSTIC_APP};

use abscissa_core::{Command, Runnable, Shutdown};
use anyhow::{bail, Result};

use rustic_core::repofile::{IndexFile, IndexId, KeyId, PackId, SnapshotId};

/// `list` subcommand
#[derive(clap::Parser, Command, Debug)]
pub(crate) struct ListCmd {
    /// File types to list
    #[clap(value_parser=["blobs", "indexpacks", "indexcontent", "index", "packs", "snapshots", "keys"])]
    tpe: String,
}

impl Runnable for ListCmd {
    fn run(&self) {
        if let Err(err) = RUSTIC_APP
            .config()
            .repository
            .run_open(|repo| self.inner_run(repo))
        {
            status_err!("{}", err);
            RUSTIC_APP.shutdown(Shutdown::Crash);
        };
    }
}

impl ListCmd {
    fn inner_run(&self, repo: CliOpenRepo) -> Result<()> {
        match self.tpe.as_str() {
            // special treatment for listing blobs: read the index and display it
            "blobs" | "indexpacks" | "indexcontent" => {
                for item in repo.stream_files::<IndexFile>()? {
                    let (_, index) = item?;
                    for pack in index.packs {
                        match self.tpe.as_str() {
                            "blobs" => {
                                for blob in pack.blobs {
                                    println!("{:?} {:?}", blob.tpe, blob.id);
                                }
                            }
                            "indexcontent" => {
                                for blob in pack.blobs {
                                    println!(
                                        "{:?} {:?} {:?} {} {}",
                                        blob.tpe,
                                        blob.id,
                                        pack.id,
                                        blob.length,
                                        blob.uncompressed_length.map_or(0, NonZero::get)
                                    );
                                }
                            }
                            "indexpacks" => println!(
                                "{:?} {:?} {} {}",
                                pack.blob_type(),
                                pack.id,
                                pack.pack_size(),
                                pack.time.map_or_else(String::new, |time| format!(
                                    "{}",
                                    time.format("%Y-%m-%d %H:%M:%S")
                                ))
                            ),
                            t => {
                                bail!("invalid type: {}", t);
                            }
                        }
                    }
                }
            }
            "index" => {
                for id in repo.list::<IndexId>()? {
                    println!("{id:?}");
                }
            }
            "packs" => {
                for id in repo.list::<PackId>()? {
                    println!("{id:?}");
                }
            }
            "snapshots" => {
                for id in repo.list::<SnapshotId>()? {
                    println!("{id:?}");
                }
            }
            "keys" => {
                for id in repo.list::<KeyId>()? {
                    println!("{id:?}");
                }
            }
            t => {
                bail!("invalid type: {}", t);
            }
        };

        Ok(())
    }
}