chiark / gitweb /
svg size handling: Introduce SVGWidthOrHeight
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 2 May 2022 10:58:36 +0000 (11:58 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 2 May 2022 11:18:04 +0000 (12:18 +0100)
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 <ijackson@chiark.greenend.org.uk>
src/prelude.rs
src/utils.rs

index 71f18b09ea9f96159cd613a12805af2bf2021f61..6717aa23f709af7f8287d57307ab0e0ae62dcbe2 100644 (file)
@@ -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;
index 023d97641e931fbe649b83730a1f83c6817f49f3..e4770deface3eb5e546934e0cad01187356f5fa1 100644 (file)
@@ -216,14 +216,21 @@ impl<T> Index<OldNewIndex> for OldNew<T> {
 
 #[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 <svg>")] 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<PosC<f64>> {
   let mut tokens = xmlparser::Tokenizer::from(xml)
@@ -243,22 +250,26 @@ pub fn svg_parse_size(xml: &str) -> Option<PosC<f64>> {
   }
 
   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 }