Skip to main content

knf/
cli.rs

1//! clap derive structs.
2
3use std::path::PathBuf;
4
5use clap::Parser;
6use knf_dotted::PathLeaf;
7
8use crate::format::Format;
9
10#[derive(Parser, Debug)]
11#[command(
12    name = "knf",
13    version,
14    about = "Merge layered configuration files and print the result",
15    long_about = "\
16Merge layered configuration files and print the result.
17
18Files are layers, merged left to right in argument order. JSON and TOML may be
19mixed freely. Exactly one document goes to stdout.
20
21  knf base.toml prod.toml
22  knf base.json - --input-format json          # stdin as a layer
23  knf defaults.json --set server.port=8080 -f toml
24
25Objects merge key by key. Arrays, scalars and null all replace wholesale —
26null is an ordinary value that overwrites, not a delete instruction."
27)]
28pub struct Cli {
29    /// Files to merge as layers; `-` reads stdin
30    #[arg(value_name = "FILE")]
31    pub files: Vec<PathBuf>,
32
33    /// Treat every input as this format; required for `-`
34    #[arg(
35        long,
36        value_name = "FORMAT",
37        long_help = "\
38Treat every input as this format, overriding extension inference.
39
40Required for `-`, which has no extension. Note that it applies to all inputs,
41not only stdin, so it cannot be used to mix a stdin layer of one format with
42files of another."
43    )]
44    pub input_format: Option<Format>,
45
46    /// Inline terminal layer, applied after all files
47    #[arg(
48        long = "set",
49        value_name = "KEY.PATH=VALUE",
50        long_help = "\
51Inline terminal layer, applied after all files. Repeatable; multiple --set apply
52left to right.
53
54The value is parsed as JSON, falling back to a string when that fails:
55
56  port=8080       -> 8080     (number)
57  debug=true      -> true     (bool)
58  name=foo        -> \"foo\"    (not valid JSON, so a string)
59  proxy=null      -> null     (an error under -f toml, like any other null)
60  tags=[\"a\",\"b\"]  -> array
61  tags=[a,b]      -> \"[a,b]\"  (not valid JSON, so a string)
62
63Sharp edge: version=1.0 is the number 1.0, not the string \"1.0\". Force a string
64by quoting into JSON: --set version='\"1.0\"'.
65
66Dotted paths nest, so keys containing a literal dot are not addressable from
67--set; use a file."
68    )]
69    pub set: Vec<PathLeaf<String>>,
70
71    /// Output format; required when inputs are mixed
72    #[arg(short = 'f', long, value_name = "FORMAT")]
73    pub format: Option<Format>,
74
75    /// Error when a layer changes the type of an existing key
76    #[arg(long)]
77    pub strict: bool,
78
79    /// Disable pretty-printing
80    #[arg(long)]
81    pub compact: bool,
82}