Add documentation

This commit is contained in:
Austen Adler 2024-09-03 23:25:22 -04:00
parent 466e14bcc9
commit 204dfec1dd

View File

@ -20,7 +20,9 @@ struct Cli {
#[derive(Subcommand, Debug)]
enum Command {
#[clap(about = "Format a single file or stdin")]
Fmt(FmtArgs),
#[clap(about = "Watch a file or directory for changes")]
Watch(WatchArgs),
}
@ -28,31 +30,36 @@ enum Command {
struct WatchArgs {
path: PathBuf,
#[clap(short = 'e', long = "extension", default_values = ["jsonc", "jsoncc"])]
#[clap(short = 'e', long = "extension", default_values = ["jsonc", "jsoncc"], help = "File extensions to track")]
extensions: Vec<OsString>,
#[clap(short = 'r', long = "recursive")]
#[clap(short = 'r', long = "recursive", help = "Recursively search files")]
recursive: bool,
#[clap(short = 'I', long = "inplace")]
#[clap(short = 'I', long = "inplace", help = "Replace each file inplace")]
inplace: bool,
}
#[derive(Args, Debug)]
struct FmtArgs {
// #[clap(short = 'i', long = "input")]
input: PathBuf,
#[clap(help = "Input file, or `-` for stdin")]
input: Option<PathBuf>,
#[clap(short = 'o', long = "output")]
#[clap(
short = 'o',
long = "output",
help = "Output file; will be stdout if no output is specified"
)]
output: Option<PathBuf>,
#[clap(short = 'O', long = "json-output")]
#[clap(short = 'O', long = "json-output", help = "Output file for json")]
json_output: Option<PathBuf>,
#[clap(short = 'c', long = "compact")]
#[clap(short = 'c', long = "compact", help = "Compact json format")]
compact: bool,
#[clap(short = 'I', long = "inplace")]
#[clap(short = 'I', long = "inplace", help = "Replace file contents inplace")]
inplace: bool,
}
@ -60,7 +67,9 @@ impl FmtArgs {
/// Where should we format Jsonc output to?
fn jsonc_output(&self) -> Option<JsoncOutput> {
if self.inplace {
Some(JsoncOutput::File(&self.input))
Some(JsoncOutput::File(self.input.as_ref().expect(
"Argument parsing error -- input was empty, but --inplace was specified",
)))
} else if let Some(ref output_file) = &self.output {
Some(JsoncOutput::File(output_file))
} else if self.json_output.is_some() {
@ -81,8 +90,6 @@ enum JsoncOutput<'a> {
fn main() -> Result<()> {
let options = Cli::parse();
eprintln!("Options: {options:?}");
match options.command {
Command::Fmt(a) => {
// TODO: Figure out how to validate this in clap Parser
@ -93,7 +100,7 @@ fn main() -> Result<()> {
bail!("Cannot format --inplace when --output is specified");
}
format_single_file(
&a.input,
a.input.as_ref(),
a.jsonc_output().as_ref(),
a.json_output.as_ref(),
a.compact,
@ -106,21 +113,25 @@ fn main() -> Result<()> {
}
fn format_single_file(
input: impl AsRef<Path>,
input: Option<impl AsRef<Path>>,
jsonc_output: Option<&JsoncOutput>,
json_output: Option<impl AsRef<Path>>,
json_compact: bool,
) -> Result<()> {
let input_str = fs::read_to_string(&input).context("Reading input")?;
let input_str = if let Some(input_filename) = input {
fs::read_to_string(&input_filename).context("Reading input")?
} else {
std::io::read_to_string(std::io::stdin()).context("Reading stdin")?
};
// First, format jsonc
if let Some(jsonc_output) = jsonc_output {
let output = fjson::to_jsonc(&input_str).context("Formatting to jsonc")?;
let output = fjson::to_jsonc(&input_str).context("Parsing jsonc")?;
match jsonc_output {
JsoncOutput::Stdout => print!("{output}"),
JsoncOutput::File(output_file) => AtomicFile::new(output_file, AllowOverwrite)
.write(|f| f.write_all(&output.as_bytes()))
.write(|f| f.write_all(output.as_bytes()))
.context("Writing jsonc output")?,
}
}
@ -133,9 +144,13 @@ fn format_single_file(
fjson::to_json_compact(&input_str).context("Formatting to json")
}?;
AtomicFile::new(json_output_file, AllowOverwrite)
.write(|f| f.write_all(&output.as_bytes()))
.context("Writing jsonc output")?;
if json_output_file.as_ref().as_os_str() == "-" {
print!("{output}");
} else {
AtomicFile::new(json_output_file, AllowOverwrite)
.write(|f| f.write_all(output.as_bytes()))
.context("Writing jsonc output")?;
}
}
Ok(())
@ -181,7 +196,7 @@ fn watch(args: &WatchArgs) -> Result<()> {
if !(args
.extensions
.iter()
.any(|ext| (&path).extension() == Some(ext))
.any(|ext| path.extension() == Some(ext))
|| args.extensions.is_empty())
{
// This extension doesn't match their requested extensions
@ -196,7 +211,7 @@ fn watch(args: &WatchArgs) -> Result<()> {
eprintln!("Got result: {path:#?}");
match format_single_file(
&path,
Some(&path),
Some(&JsoncOutput::File(&path)),
None::<&Path>,
false,