kdl_fmt/config/
mod.rs

1use clap::Parser;
2use miette::{bail, IntoDiagnostic, Result};
3
4use super::kdl::KdlVersion;
5
6mod args;
7mod file;
8
9#[derive(Default, Clone)]
10pub struct Config {
11    // version constraints
12    pub assume_format: Option<KdlVersion>,
13    pub ensure_format: Option<KdlVersion>,
14
15    // input
16    pub content: String,
17    pub filename: Option<String>,
18
19    // format config
20    pub strip_comments: bool,
21    pub indent_level: usize,
22
23    // misc. config
24    pub no_format: bool,
25    pub in_place: bool,
26}
27
28impl Config {
29    pub fn new(args: &args::Args) -> Result<Self> {
30        let mut conf = Self::from_config_file_or_default()?;
31        conf.merge_args(args);
32        Ok(conf)
33    }
34
35    fn from_config_file_or_default() -> Result<Self> {
36        let mut conf = Config::default();
37
38        if let Some(config_file_config) = file::get_config_file()? {
39            conf.assume_format = config_file_config.assume_version;
40            conf.ensure_format = config_file_config.ensure_version;
41
42            if let Some(indent_level) = config_file_config.indent_level {
43                conf.indent_level = indent_level;
44            }
45
46            if let Some(strip_comments) = config_file_config.strip_comments {
47                conf.strip_comments = strip_comments;
48            }
49        }
50
51        Ok(conf)
52    }
53
54    fn merge_args(&mut self, args: &args::Args) -> &mut Self {
55        if args.from_v1 || args.from_v2 {
56            self.assume_format = args::get_version_from_flags(args.from_v1, args.from_v2);
57        }
58
59        if args.to_v1 || args.to_v2 {
60            self.ensure_format = args::get_version_from_flags(args.to_v1, args.to_v2);
61        }
62
63        if args.strip_comments {
64            self.strip_comments = true;
65        }
66
67        if let Some(level) = args.indent_level {
68            self.indent_level = level;
69        }
70
71        self.no_format = args.no_format;
72        self.in_place = args.in_place;
73        self
74    }
75}
76
77pub fn get_config() -> Result<Config> {
78    let args = args::Args::parse();
79
80    if args.to_v1 && args.to_v2 {
81        bail!("Cannot output in v1 and v2 spec at the same time");
82    }
83
84    if args.input.is_stdin() && args.in_place {
85        bail!("Cannot format STDIN with --in-place, due to missing filename");
86    }
87
88    let mut conf = Config::new(&args)?;
89
90    conf.content = args.input.clone().contents().into_diagnostic()?;
91    conf.filename = match args.input.is_file() {
92        true => Some(args.input.filename().to_owned()),
93        false => None,
94    };
95
96    Ok(conf)
97}