Implement FromStr for SVGMeasure

This commit is contained in:
Elnu 2023-08-14 12:46:19 -07:00
parent 5254d3dc8f
commit dc636263b7
5 changed files with 93 additions and 1 deletions

View file

@ -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"

View file

@ -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<Self, Self::Err> {
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::<f64>()?;
let unit = captures[2].parse::<SVGUnit>()?;
Ok(SVGMeasure::new(measure, unit))
} else {
Err(SVGUnitParseError::Invalid)
}
}
}
const EQ_TOLERANCE: f64 = 0.00001;
impl PartialEq for SVGMeasure {

View file

@ -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());
}