From dc636263b7b315d45c2c2d7f14a94b9eeca25081 Mon Sep 17 00:00:00 2001 From: ElnuDev Date: Mon, 14 Aug 2023 12:46:19 -0700 Subject: [PATCH] Implement FromStr for SVGMeasure --- Cargo.lock | 46 ++++++++++++++++++++++++++++++++++ dyesub-tool/Cargo.toml | 2 ++ dyesub-tool/src/svg/measure.rs | 32 +++++++++++++++++++++++ dyesub-tool/src/svg/tests.rs | 12 +++++++++ flake.nix | 2 +- 5 files changed, 93 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 8ae7457..3d7b096 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" +dependencies = [ + "memchr", +] + [[package]] name = "askama" version = "0.12.0" @@ -77,6 +86,8 @@ version = "0.1.0" dependencies = [ "askama", "derive_more", + "lazy_static", + "regex", "strum", "strum_macros", ] @@ -96,6 +107,12 @@ dependencies = [ "libm", ] +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libm" version = "0.2.7" @@ -173,6 +190,35 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "regex" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" + [[package]] name = "rustc_version" version = "0.4.0" diff --git a/dyesub-tool/Cargo.toml b/dyesub-tool/Cargo.toml index a67246a..a99af79 100644 --- a/dyesub-tool/Cargo.toml +++ b/dyesub-tool/Cargo.toml @@ -6,5 +6,7 @@ edition = "2021" [dependencies] askama = "0.12.0" derive_more = "0.99.17" +lazy_static = "1.4.0" +regex = "1.9.3" strum = "0.25.0" strum_macros = "0.25.2" diff --git a/dyesub-tool/src/svg/measure.rs b/dyesub-tool/src/svg/measure.rs index 7f442aa..3e23764 100644 --- a/dyesub-tool/src/svg/measure.rs +++ b/dyesub-tool/src/svg/measure.rs @@ -1,10 +1,16 @@ use super::SVGUnit; use std::cmp::Ordering; use std::fmt; +use std::num::ParseFloatError; +use std::str::FromStr; use std::{ fmt::Display, ops::{Add, Div, Mul, Sub}, }; +use lazy_static::lazy_static; +use regex::Regex; +use derive_more::From; +use strum::ParseError; #[derive(Debug, Clone, Copy)] pub struct SVGMeasure { @@ -29,6 +35,32 @@ impl SVGMeasure { } } +#[derive(From, Debug)] +pub enum SVGUnitParseError { + ParseMeasure(ParseFloatError), + ParseUnit(ParseError), + Invalid, +} + +impl FromStr for SVGMeasure { + type Err = SVGUnitParseError; + fn from_str(s: &str) -> Result { + if s == "0" { + return Ok(SVGMeasure::new(0.0, SVGUnit::Pixel)); + } + lazy_static! { + static ref RE: Regex = Regex::new(r"^([\d.]+)([a-zA-Z]+)$").unwrap(); + } + if let Some(captures) = RE.captures(s) { + let measure = captures[1].parse::()?; + let unit = captures[2].parse::()?; + Ok(SVGMeasure::new(measure, unit)) + } else { + Err(SVGUnitParseError::Invalid) + } + } +} + const EQ_TOLERANCE: f64 = 0.00001; impl PartialEq for SVGMeasure { diff --git a/dyesub-tool/src/svg/tests.rs b/dyesub-tool/src/svg/tests.rs index fd57bd3..1c666b9 100644 --- a/dyesub-tool/src/svg/tests.rs +++ b/dyesub-tool/src/svg/tests.rs @@ -1,3 +1,5 @@ +use std::str::FromStr; + use crate::svg::{SVGMeasure, SVGUnit}; #[test] @@ -52,3 +54,13 @@ fn cmp() { assert!(m_10cm > m_5mm); assert!(m_5mm < m_10cm); } + +#[test] +fn from_str() { + let m_10cm = SVGMeasure::new(10.0, SVGUnit::Centimeter); + let m_5mm = SVGMeasure::new(5.0, SVGUnit::Millimeter); + let m_0 = SVGMeasure::new(0.0, SVGUnit::Pixel); + assert_eq!(m_10cm, SVGMeasure::from_str("10cm").unwrap()); + assert_eq!(m_5mm, SVGMeasure::from_str("5mm").unwrap()); + assert_eq!(m_0, SVGMeasure::from_str("0").unwrap()); +} \ No newline at end of file diff --git a/flake.nix b/flake.nix index 7042f94..7abf022 100644 --- a/flake.nix +++ b/flake.nix @@ -51,7 +51,7 @@ Updating `cargoHash`: pname = "dyesub-tool"; version = "0.1.0"; buildAndTestSubdir = "dyesub-tool"; - cargoHash = "sha256-WUA3ysG7SlylV1y5nkPxLRGVa4NktFjpawE97d3b36I="; + cargoHash = "sha256-QlLyKDZZ+/bB4xBv0j9GoL6Ur3Okdskkazi4WlHhx6Y="; meta = meta // { description = "A tool for generating dye sublimation transfer sheet SVGs for Japanese thumb shift 拇指シフト keycaps."; };