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 pub assume_format: Option<KdlVersion>,
13 pub ensure_format: Option<KdlVersion>,
14
15 pub content: String,
17 pub filename: Option<String>,
18
19 pub strip_comments: bool,
21 pub indent_level: usize,
22
23 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}