rustic_rs/commands/
cat.rs1use crate::{status_err, Application, RUSTIC_APP};
4
5use abscissa_core::{Command, Runnable, Shutdown};
6
7use anyhow::Result;
8
9use rustic_core::repofile::{BlobType, FileType};
10
11#[derive(clap::Parser, Command, Debug)]
15pub(crate) struct CatCmd {
16 #[clap(subcommand)]
17 cmd: CatSubCmd,
18}
19
20#[derive(clap::Subcommand, Debug)]
22enum CatSubCmd {
23 TreeBlob(IdOpt),
25 DataBlob(IdOpt),
27 Config,
29 Index(IdOpt),
31 Snapshot(IdOpt),
33 Tree(TreeOpts),
35}
36
37#[derive(Default, clap::Parser, Debug)]
38struct IdOpt {
39 id: String,
41}
42
43#[derive(clap::Parser, Debug)]
44struct TreeOpts {
45 #[clap(value_name = "SNAPSHOT[:PATH]")]
47 snap: String,
48}
49
50impl Runnable for CatCmd {
51 fn run(&self) {
52 if let Err(err) = self.inner_run() {
53 status_err!("{}", err);
54 RUSTIC_APP.shutdown(Shutdown::Crash);
55 };
56 }
57}
58
59impl CatCmd {
60 fn inner_run(&self) -> Result<()> {
61 let config = RUSTIC_APP.config();
62 let data = match &self.cmd {
63 CatSubCmd::Config => config
64 .repository
65 .run_open(|repo| Ok(repo.cat_file(FileType::Config, "")?))?,
66 CatSubCmd::Index(opt) => config
67 .repository
68 .run_open(|repo| Ok(repo.cat_file(FileType::Index, &opt.id)?))?,
69 CatSubCmd::Snapshot(opt) => config
70 .repository
71 .run_open(|repo| Ok(repo.cat_file(FileType::Snapshot, &opt.id)?))?,
72 CatSubCmd::TreeBlob(opt) => config
73 .repository
74 .run_indexed(|repo| Ok(repo.cat_blob(BlobType::Tree, &opt.id)?))?,
75 CatSubCmd::DataBlob(opt) => config
76 .repository
77 .run_indexed(|repo| Ok(repo.cat_blob(BlobType::Data, &opt.id)?))?,
78 CatSubCmd::Tree(opt) => config.repository.run_indexed(|repo| {
79 Ok(repo.cat_tree(&opt.snap, |sn| config.snapshot_filter.matches(sn))?)
80 })?,
81 };
82 println!("{}", String::from_utf8(data.to_vec())?);
83
84 Ok(())
85 }
86}