use std::path::PathBuf;
use clap::Parser;
use knf_dotted::PathLeaf;
use crate::format::Format;
#[derive(Parser, Debug)]
#[command(
name = "knf",
version,
about = "Merge layered configuration files and print the result",
long_about = "\
Merge layered configuration files and print the result.
Files are layers, merged left to right in argument order. JSON and TOML may be
mixed freely. Exactly one document goes to stdout.
knf base.toml prod.toml
knf base.json - --input-format json # stdin as a layer
knf defaults.json --set server.port=8080 -f toml
Objects merge key by key. Arrays, scalars and null all replace wholesale —
null is an ordinary value that overwrites, not a delete instruction."
)]
pub struct Cli {
#[arg(value_name = "FILE")]
pub files: Vec<PathBuf>,
#[arg(
long,
value_name = "FORMAT",
long_help = "\
Treat every input as this format, overriding extension inference.
Required for `-`, which has no extension. Note that it applies to all inputs,
not only stdin, so it cannot be used to mix a stdin layer of one format with
files of another."
)]
pub input_format: Option<Format>,
#[arg(
long = "set",
value_name = "KEY.PATH=VALUE",
long_help = "\
Inline terminal layer, applied after all files. Repeatable; multiple --set apply
left to right.
The value is parsed as JSON, falling back to a string when that fails:
port=8080 -> 8080 (number)
debug=true -> true (bool)
name=foo -> \"foo\" (not valid JSON, so a string)
proxy=null -> null (an error under -f toml, like any other null)
tags=[\"a\",\"b\"] -> array
tags=[a,b] -> \"[a,b]\" (not valid JSON, so a string)
Sharp edge: version=1.0 is the number 1.0, not the string \"1.0\". Force a string
by quoting into JSON: --set version='\"1.0\"'.
Dotted paths nest, so keys containing a literal dot are not addressable from
--set; use a file."
)]
pub set: Vec<PathLeaf<String>>,
#[arg(short = 'f', long, value_name = "FORMAT")]
pub format: Option<Format>,
#[arg(long)]
pub strict: bool,
#[arg(long)]
pub compact: bool,
}