Bladeren bron

Add parameter support for pen range

Kevin Lee 6 maanden geleden
bovenliggende
commit
8d3da0a272
3 gewijzigde bestanden met toevoegingen van 52 en 10 verwijderingen
  1. 5 4
      Cargo.lock
  2. 1 0
      Cargo.toml
  3. 46 6
      src/main.rs

+ 5 - 4
Cargo.lock

@@ -346,6 +346,7 @@ dependencies = [
  "num",
  "num_enum",
  "rand",
+ "regex",
  "serde",
  "serde_repr",
  "serde_yaml",
@@ -542,9 +543,9 @@ dependencies = [
 
 [[package]]
 name = "regex"
-version = "1.10.2"
+version = "1.10.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
+checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -554,9 +555,9 @@ dependencies = [
 
 [[package]]
 name = "regex-automata"
-version = "0.4.3"
+version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
+checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
 dependencies = [
  "aho-corasick",
  "memchr",

+ 1 - 0
Cargo.toml

@@ -26,6 +26,7 @@ modular-bitfield = "0.11.2"
 num = "0.4.1"
 num_enum = "0.7.1"
 rand = "0.8.5"
+regex = "1.10.4"
 serde = { version = "1.0.193", features = ["derive"] }
 serde_repr = "0.1.18"
 serde_yaml = "0.9.29"

+ 46 - 6
src/main.rs

@@ -1,17 +1,19 @@
 use std::{
     fs::File,
     io::{Cursor, Read, Write},
+    ops::RangeInclusive,
     path::PathBuf,
     time::Instant,
 };
 
 use binrw::{BinRead, BinWrite, BinWriterExt};
-use clap::{Args, Parser, Subcommand};
+use clap::{error::ErrorKind, Args, Error, Parser, Subcommand};
 use clap_verbosity_flag::{InfoLevel, Verbosity};
 use diff::Diff;
 use env_logger::Target;
 use ezcad::{file::EzCadHeader, layer::Layer, objects::Object};
 use log::{info, trace, warn};
+use regex::Regex;
 
 use crate::config::{Config, Operations};
 
@@ -45,14 +47,52 @@ struct DiffCmd {
     diff_file: PathBuf,
 }
 
+fn parse_range(arg: &str) -> Result<RangeInclusive<usize>, Error> {
+    let re: Regex = Regex::new(r"(\d+)?(\.{2})?(=)?(\d+)?").unwrap();
+    const PEN_MAX: usize = 255;
+
+    match re.captures(arg) {
+        Some(found) => {
+            let range: bool = found.get(2).is_some();
+            let inclusive: bool = found.get(3).is_some();
+            let d1: Option<usize> = found
+                .get(1)
+                .map(|x| usize::from_str_radix(x.as_str(), 10).unwrap());
+            let d2: Option<usize> = found
+                .get(4)
+                .map(|x| usize::from_str_radix(x.as_str(), 10).unwrap());
+
+            let ret = |d1: usize, d2: usize, inclusive: bool| -> RangeInclusive<usize> {
+                match inclusive {
+                    true => d1..=d2,
+                    false => d1..=(d2 - 1),
+                }
+            };
+
+            match (d1, d2) {
+                (None, None) if range => Ok(0..=PEN_MAX),
+                (None, None) => Err(Error::new(ErrorKind::InvalidValue)),
+                (Some(d1), None) if !range => Ok(d1..=d1),
+                (Some(d1), None) => Ok(ret(d1, PEN_MAX, true)),
+                (None, Some(d2)) if !range => Ok(d2..=d2),
+                (None, Some(d2)) => Ok(ret(0, d2, inclusive)),
+                (Some(d1), Some(d2)) if d1 > d2 => Err(Error::new(ErrorKind::InvalidValue)),
+                (Some(d1), Some(d2)) => Ok(ret(d1, d2, inclusive)),
+            }
+        }
+        _ => Err(Error::new(ErrorKind::InvalidValue)),
+    }
+}
+
 /// Queries input .mlp file for pen or object info
 #[derive(Debug, Args)]
 struct QueryCmd {
-    /// Print pen info
+    /// Print info for pens
     #[arg(short, long)]
-    pen: Option<Vec<usize>>,
+    #[arg(value_parser = parse_range)]
+    pen: Option<RangeInclusive<usize>>,
 
-    /// Print object info
+    /// Print info for objects
     #[arg(short, long)]
     object: Option<usize>,
 
@@ -164,8 +204,8 @@ fn main() {
             }
 
             // Process pen query
-            args.pen.map(|pens| {
-                for pen in pens {
+            args.pen.map(|pen_range| {
+                for pen in pen_range {
                     info!(
                         "Pen #{}: {}",
                         pen,