codeberg_cli/actions/config/
info.rs

1use config::ValueKind;
2use itertools::Itertools;
3use miette::IntoDiagnostic;
4
5use crate::{
6    actions::GlobalArgs,
7    render::json::JsonToStdout,
8    types::{config::BergConfig, output::OutputMode},
9};
10
11use clap::Parser;
12
13/// Display short overview of which config values are used
14#[derive(Parser, Debug)]
15pub struct ConfigInfoArgs {}
16
17impl ConfigInfoArgs {
18    pub fn run(self, global_args: GlobalArgs) -> miette::Result<()> {
19        // use the raw config since it contains the origin of field
20        let raw_config = BergConfig::raw()?;
21        let config = BergConfig::new()?;
22
23        match global_args.output_mode {
24            OutputMode::Pretty => present_config_info(config, raw_config)?,
25            OutputMode::Json => config.print_json()?,
26        };
27
28        Ok(())
29    }
30}
31
32fn present_config_info(config: BergConfig, raw_config: config::Config) -> miette::Result<()> {
33    let table = config
34        .make_table()
35        .set_header(vec!["Field", "Source", "Value"])
36        .add_rows(
37            raw_config
38                .cache
39                .into_table()
40                .into_diagnostic()?
41                .into_iter()
42                .sorted_by_key(|(k, _)| k.to_string())
43                .map(|(k, v)| {
44                    // this is a bit difficult since the lib doesn't make the field public
45                    let origin = {
46                        let dbg = format!("{v:?}");
47                        dbg.find("origin: ").map_or_else(
48                            || String::from("Default"),
49                            |idx| {
50                                let origin = dbg
51                                    .chars()
52                                    .skip(idx)
53                                    .skip("origin: ".len())
54                                    .take_while(|&c| c != ',')
55                                    .collect::<String>();
56
57                                match origin.as_str() {
58                                    "None" => String::from("Default"),
59                                    s if s.starts_with("Some(") => {
60                                        s.replace("Some(", "").replace(')', "")
61                                    }
62                                    s => s.to_string(),
63                                }
64                            },
65                        )
66                    };
67                    let v = {
68                        let is_string = matches!(v.kind, ValueKind::String(_));
69                        if is_string {
70                            format!("{:?}", v.to_string())
71                        } else {
72                            v.to_string()
73                        }
74                    };
75                    vec![k, origin, v]
76                }),
77        );
78
79    println!("{table}", table = table.show());
80
81    Ok(())
82}