From a9269e7dd195060cbed1c5b3b1a08b3a67ea7aac Mon Sep 17 00:00:00 2001 From: JMARyA Date: Mon, 6 Nov 2023 09:58:08 +0100 Subject: [PATCH] refactor --- README.md | 24 ++++++++++ src/main.rs | 130 +++++++++++++++++++++++++++++----------------------- 2 files changed, 97 insertions(+), 57 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..0273843 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# mdpatch + +Patch the frontmatter of markdown files + +# Usage +``` +Usage: mdpatch [OPTIONS] + +Arguments: + Markdown File + +Options: + -p, --patch Apply JSON Patch file. If set to '-' read from stdin + --merge Merge Markdown frontmatter. If set to '-' read from stdin + -a, --add Only patch add operations + -m, --modify Only patch modify operations + -d, --delete Only patch delete operations + -v, --verbose Print out what changes will be made to the document + -n, --dryrun Dont modify the input file. Only print what would be done + -o, --output Write patched file to output path. Dont modify the input file directly. If set to '-' output to stdout + --notest Ignore tests in JSON Patch files + -x, --exclude Exclude json path from patch + -k, --keys Only include the specified json paths in patch +``` \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 7ad4892..080aae2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -183,6 +183,54 @@ fn exclude_json_by_paths(paths: &[String], json_value: &Value) -> Value { } } +fn explain_patch_verbose(patch: Vec) { + for op in patch { + match op { + PatchOperation::Add(op) => { + eprintln!( + "Add {} at {}", + console::Style::new().green().apply_to(op.value), + console::Style::new().bright().red().apply_to(op.path) + ); + } + PatchOperation::Remove(op) => { + eprintln!( + "Remove value at {}", + console::Style::new().bright().red().apply_to(op.path) + ); + } + PatchOperation::Replace(op) => { + eprintln!( + "Replace value at {} with {}", + console::Style::new().bright().red().apply_to(op.path), + console::Style::new().green().apply_to(op.value) + ); + } + PatchOperation::Move(op) => { + eprintln!( + "Move value from {} to {}", + console::Style::new().bright().red().apply_to(op.from), + console::Style::new().green().apply_to(op.path) + ); + } + PatchOperation::Copy(op) => { + eprintln!( + "Copy value from {} to {}", + console::Style::new().bright().red().apply_to(op.from), + console::Style::new().green().apply_to(op.path) + ); + } + PatchOperation::Test(op) => { + eprintln!( + "Test value at {} for {}", + console::Style::new().bright().red().apply_to(op.path), + console::Style::new().green().apply_to(op.value) + ); + } + } + } +} + fn main() { let args = args::get_args(); @@ -245,51 +293,7 @@ fn main() { let patch: Vec = serde_json::from_value(patch).unwrap(); if args.get_flag("verbose") | args.get_flag("dryrun") { - for op in patch.clone() { - match op { - PatchOperation::Add(op) => { - eprintln!( - "Add {} at {}", - console::Style::new().green().apply_to(op.value), - console::Style::new().bright().red().apply_to(op.path) - ); - } - PatchOperation::Remove(op) => { - eprintln!( - "Remove value at {}", - console::Style::new().bright().red().apply_to(op.path) - ); - } - PatchOperation::Replace(op) => { - eprintln!( - "Replace value at {} with {}", - console::Style::new().bright().red().apply_to(op.path), - console::Style::new().green().apply_to(op.value) - ); - } - PatchOperation::Move(op) => { - eprintln!( - "Move value from {} to {}", - console::Style::new().bright().red().apply_to(op.from), - console::Style::new().green().apply_to(op.path) - ); - } - PatchOperation::Copy(op) => { - eprintln!( - "Copy value from {} to {}", - console::Style::new().bright().red().apply_to(op.from), - console::Style::new().green().apply_to(op.path) - ); - } - PatchOperation::Test(op) => { - eprintln!( - "Test value at {} for {}", - console::Style::new().bright().red().apply_to(op.path), - console::Style::new().green().apply_to(op.value) - ); - } - } - } + explain_patch_verbose(patch.clone()); } if !args.get_flag("dryrun") { @@ -317,18 +321,30 @@ fn main() { } } else if let Some(merge_file) = args.get_one::("merge") { // TODO : Add support for merging frontmatter from markdown file - let mut merge_doc: serde_json::Value = serde_json::from_str( - &(if merge_file == "-" { - let mut str = String::new(); - std::io::stdin() - .read_to_string(&mut str) - .quit_on_error("Coult not read stdin"); - str - } else { - std::fs::read_to_string(merge_file).quit_on_error("Could not read merge file") - }), - ) - .quit_on_error("Could not parse merge file"); + let merge_file_content = if merge_file == "-" { + let mut str = String::new(); + std::io::stdin() + .read_to_string(&mut str) + .quit_on_error("Coult not read stdin"); + str + } else { + std::fs::read_to_string(merge_file).quit_on_error("Could not read merge file") + }; + + let mut merge_doc: serde_json::Result = + serde_json::from_str(&merge_file_content); + + if merge_doc.is_err() { + let (frontmatter, _) = markdown_with_frontmatter(&merge_file_content); + let frontmatter = frontmatter + .ok_or(0) + .quit_on_error("Could not get merge file frontmatter"); + let frontmatter_val: serde_yaml::Value = serde_yaml::from_str(&frontmatter) + .quit_on_error("Could not parse merge file frontmatter"); + merge_doc = serde_json::to_value(frontmatter_val) + } + + let mut merge_doc = merge_doc.quit_on_error("Parsing merge file failed"); if let Some(excludes) = args.get_many::("exclude") { let excludes: Vec = excludes.cloned().collect();