Add documentation
This commit is contained in:
parent
466e14bcc9
commit
204dfec1dd
53
src/main.rs
53
src/main.rs
@ -20,7 +20,9 @@ struct Cli {
|
|||||||
|
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug)]
|
||||||
enum Command {
|
enum Command {
|
||||||
|
#[clap(about = "Format a single file or stdin")]
|
||||||
Fmt(FmtArgs),
|
Fmt(FmtArgs),
|
||||||
|
#[clap(about = "Watch a file or directory for changes")]
|
||||||
Watch(WatchArgs),
|
Watch(WatchArgs),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,31 +30,36 @@ enum Command {
|
|||||||
struct WatchArgs {
|
struct WatchArgs {
|
||||||
path: PathBuf,
|
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>,
|
extensions: Vec<OsString>,
|
||||||
|
|
||||||
#[clap(short = 'r', long = "recursive")]
|
#[clap(short = 'r', long = "recursive", help = "Recursively search files")]
|
||||||
recursive: bool,
|
recursive: bool,
|
||||||
|
|
||||||
#[clap(short = 'I', long = "inplace")]
|
#[clap(short = 'I', long = "inplace", help = "Replace each file inplace")]
|
||||||
inplace: bool,
|
inplace: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Args, Debug)]
|
#[derive(Args, Debug)]
|
||||||
struct FmtArgs {
|
struct FmtArgs {
|
||||||
// #[clap(short = 'i', long = "input")]
|
// #[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>,
|
output: Option<PathBuf>,
|
||||||
|
|
||||||
#[clap(short = 'O', long = "json-output")]
|
#[clap(short = 'O', long = "json-output", help = "Output file for json")]
|
||||||
json_output: Option<PathBuf>,
|
json_output: Option<PathBuf>,
|
||||||
|
|
||||||
#[clap(short = 'c', long = "compact")]
|
#[clap(short = 'c', long = "compact", help = "Compact json format")]
|
||||||
compact: bool,
|
compact: bool,
|
||||||
|
|
||||||
#[clap(short = 'I', long = "inplace")]
|
#[clap(short = 'I', long = "inplace", help = "Replace file contents inplace")]
|
||||||
inplace: bool,
|
inplace: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +67,9 @@ impl FmtArgs {
|
|||||||
/// Where should we format Jsonc output to?
|
/// Where should we format Jsonc output to?
|
||||||
fn jsonc_output(&self) -> Option<JsoncOutput> {
|
fn jsonc_output(&self) -> Option<JsoncOutput> {
|
||||||
if self.inplace {
|
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 {
|
} else if let Some(ref output_file) = &self.output {
|
||||||
Some(JsoncOutput::File(output_file))
|
Some(JsoncOutput::File(output_file))
|
||||||
} else if self.json_output.is_some() {
|
} else if self.json_output.is_some() {
|
||||||
@ -81,8 +90,6 @@ enum JsoncOutput<'a> {
|
|||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let options = Cli::parse();
|
let options = Cli::parse();
|
||||||
|
|
||||||
eprintln!("Options: {options:?}");
|
|
||||||
|
|
||||||
match options.command {
|
match options.command {
|
||||||
Command::Fmt(a) => {
|
Command::Fmt(a) => {
|
||||||
// TODO: Figure out how to validate this in clap Parser
|
// 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");
|
bail!("Cannot format --inplace when --output is specified");
|
||||||
}
|
}
|
||||||
format_single_file(
|
format_single_file(
|
||||||
&a.input,
|
a.input.as_ref(),
|
||||||
a.jsonc_output().as_ref(),
|
a.jsonc_output().as_ref(),
|
||||||
a.json_output.as_ref(),
|
a.json_output.as_ref(),
|
||||||
a.compact,
|
a.compact,
|
||||||
@ -106,21 +113,25 @@ fn main() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn format_single_file(
|
fn format_single_file(
|
||||||
input: impl AsRef<Path>,
|
input: Option<impl AsRef<Path>>,
|
||||||
jsonc_output: Option<&JsoncOutput>,
|
jsonc_output: Option<&JsoncOutput>,
|
||||||
json_output: Option<impl AsRef<Path>>,
|
json_output: Option<impl AsRef<Path>>,
|
||||||
json_compact: bool,
|
json_compact: bool,
|
||||||
) -> Result<()> {
|
) -> 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
|
// First, format jsonc
|
||||||
if let Some(jsonc_output) = jsonc_output {
|
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 {
|
match jsonc_output {
|
||||||
JsoncOutput::Stdout => print!("{output}"),
|
JsoncOutput::Stdout => print!("{output}"),
|
||||||
JsoncOutput::File(output_file) => AtomicFile::new(output_file, AllowOverwrite)
|
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")?,
|
.context("Writing jsonc output")?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,10 +144,14 @@ fn format_single_file(
|
|||||||
fjson::to_json_compact(&input_str).context("Formatting to json")
|
fjson::to_json_compact(&input_str).context("Formatting to json")
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
|
if json_output_file.as_ref().as_os_str() == "-" {
|
||||||
|
print!("{output}");
|
||||||
|
} else {
|
||||||
AtomicFile::new(json_output_file, AllowOverwrite)
|
AtomicFile::new(json_output_file, AllowOverwrite)
|
||||||
.write(|f| f.write_all(&output.as_bytes()))
|
.write(|f| f.write_all(output.as_bytes()))
|
||||||
.context("Writing jsonc output")?;
|
.context("Writing jsonc output")?;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -181,7 +196,7 @@ fn watch(args: &WatchArgs) -> Result<()> {
|
|||||||
if !(args
|
if !(args
|
||||||
.extensions
|
.extensions
|
||||||
.iter()
|
.iter()
|
||||||
.any(|ext| (&path).extension() == Some(ext))
|
.any(|ext| path.extension() == Some(ext))
|
||||||
|| args.extensions.is_empty())
|
|| args.extensions.is_empty())
|
||||||
{
|
{
|
||||||
// This extension doesn't match their requested extensions
|
// This extension doesn't match their requested extensions
|
||||||
@ -196,7 +211,7 @@ fn watch(args: &WatchArgs) -> Result<()> {
|
|||||||
eprintln!("Got result: {path:#?}");
|
eprintln!("Got result: {path:#?}");
|
||||||
|
|
||||||
match format_single_file(
|
match format_single_file(
|
||||||
&path,
|
Some(&path),
|
||||||
Some(&JsoncOutput::File(&path)),
|
Some(&JsoncOutput::File(&path)),
|
||||||
None::<&Path>,
|
None::<&Path>,
|
||||||
false,
|
false,
|
||||||
|
Loading…
Reference in New Issue
Block a user