From: Ian Jackson Date: Mon, 2 May 2022 10:58:36 +0000 (+0100) Subject: svg size handling: Introduce SVGWidthOrHeight X-Git-Tag: otter-1.1.0~309 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=33facc30c16b8d4b8c4621acac5c7335c7db7d6a;p=otter.git svg size handling: Introduce SVGWidthOrHeight This allows us to return errors without cloning. It also means we will be able to sensibly report missing attributes when we make the size mandatory. Signed-off-by: Ian Jackson --- diff --git a/src/prelude.rs b/src/prelude.rs index 71f18b09..6717aa23 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -101,7 +101,7 @@ pub use sha2::{Sha512, Sha512_256}; pub use slotmap::{dense::DenseSlotMap, SparseSecondaryMap, Key as _}; pub use strum::{EnumCount, EnumDiscriminants}; pub use strum::{EnumString, EnumIter, EnumMessage, EnumProperty}; -pub use strum::{IntoEnumIterator, IntoStaticStr}; +pub use strum::{AsRefStr, IntoEnumIterator, IntoStaticStr}; pub use subtle::ConstantTimeEq; pub use tempfile::{self, NamedTempFile}; pub use tera::Tera; diff --git a/src/utils.rs b/src/utils.rs index 023d9764..e4770def 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -216,14 +216,21 @@ impl Index for OldNew { #[derive(Error,Clone,Serialize,Deserialize,Debug)] pub enum SVGSizeError { - #[error("parse error: {0}")] ParseError(String), - #[error("attribute {0} repeated")] AttributeRepeated(String), - #[error("attribute {0} unparseable")] AttributeUnparseable(String), + #[error("parse error: {0}")] ParseError(String), + #[error("attribute {0} repeated")] AttributeRepeated(SVGWidthOrHeight), + #[error("attribute {0} unparseable")] AttributeUnparseable(SVGWidthOrHeight), #[error("specifies only one of width and height")] OneOfWidthHeight, #[error("first element is not ")] WrongFirstElement, #[error("encountered EOF before SVG element")] UnexpectedEOF, } +#[derive(Clone,Copy,Serialize,Deserialize,Debug,AsRefStr,Display,EnumIter)] +#[allow(non_camel_case_types)] +pub enum SVGWidthOrHeight { + width, + height, +} + #[throws(SVGSizeError)] pub fn svg_parse_size(xml: &str) -> Option> { let mut tokens = xmlparser::Tokenizer::from(xml) @@ -243,22 +250,26 @@ pub fn svg_parse_size(xml: &str) -> Option> { } let mut wh = [None; 2]; + for token in &mut tokens { match token? { Tk::ElementEnd{..} => { break }, Tk::Attribute { local, value, .. } => { - let i = match local.as_str() { - "width" => 0, - "height" => 1, - _ => continue, - }; + let local = local.as_str(); + if_let!{ + Some(f) = SVGWidthOrHeight::iter().find( + |n| local == n.as_ref() + ); + else continue; + } + let i = f as usize; if wh[i].is_some() { - throw!(SvSE::AttributeRepeated(local.to_string())) + throw!(SvSE::AttributeRepeated(f)) } let v: f64 = value.parse().map_err( - |_| SvSE::AttributeUnparseable(local.to_string()) + |_| SvSE::AttributeUnparseable(f) )?; wh[i] = Some(v); if wh.iter().all(Option::is_some) { break }