[librsvg] parsers: introduce a ParseValue trait



commit f04a32415e70ce26dff3eaf1dfe11ecc87a29813
Author: Paolo Borelli <pborelli gnome org>
Date:   Sun Dec 30 12:11:06 2018 +0100

    parsers: introduce a ParseValue trait
    
    The trait is implemented for Attribute and replaces the
    corresponding functions that took the attribute as a string.

 rsvg_internals/src/clip_path.rs         |  5 +-
 rsvg_internals/src/filters/composite.rs |  4 +-
 rsvg_internals/src/filters/image.rs     |  6 +--
 rsvg_internals/src/filters/mod.rs       | 14 ++---
 rsvg_internals/src/filters/node.rs      | 27 ++++------
 rsvg_internals/src/gradient.rs          | 37 +++++--------
 rsvg_internals/src/image.rs             | 16 +++---
 rsvg_internals/src/marker.rs            | 23 ++++----
 rsvg_internals/src/mask.rs              | 22 +++-----
 rsvg_internals/src/parsers.rs           | 93 +++++++++++++++++----------------
 rsvg_internals/src/pattern.rs           | 26 ++++-----
 rsvg_internals/src/shapes.rs            | 44 +++++++---------
 rsvg_internals/src/stop.rs              |  4 +-
 rsvg_internals/src/structure.rs         | 38 +++++---------
 rsvg_internals/src/text.rs              | 18 +++----
 15 files changed, 159 insertions(+), 218 deletions(-)
---
diff --git a/rsvg_internals/src/clip_path.rs b/rsvg_internals/src/clip_path.rs
index 24d87a91..3fd25a1b 100644
--- a/rsvg_internals/src/clip_path.rs
+++ b/rsvg_internals/src/clip_path.rs
@@ -8,7 +8,7 @@ use drawing_ctx::DrawingCtx;
 use error::RenderingError;
 use handle::RsvgHandle;
 use node::{NodeResult, NodeTrait, RsvgNode};
-use parsers::parse;
+use parsers::ParseValue;
 use property_bag::PropertyBag;
 
 coord_units!(ClipPathUnits, CoordUnits::UserSpaceOnUse);
@@ -82,8 +82,7 @@ impl NodeTrait for NodeClipPath {
     fn set_atts(&self, _: &RsvgNode, _: *const RsvgHandle, pbag: &PropertyBag<'_>) -> NodeResult {
         for (attr, value) in pbag.iter() {
             match attr {
-                Attribute::ClipPathUnits => self.units.set(parse("clipPathUnits", value, ())?),
-
+                Attribute::ClipPathUnits => self.units.set(attr.parse(value, ())?),
                 _ => (),
             }
         }
diff --git a/rsvg_internals/src/filters/composite.rs b/rsvg_internals/src/filters/composite.rs
index c8869305..9c39d103 100644
--- a/rsvg_internals/src/filters/composite.rs
+++ b/rsvg_internals/src/filters/composite.rs
@@ -8,7 +8,7 @@ use drawing_ctx::DrawingCtx;
 use error::{NodeError, ValueErrorKind};
 use handle::RsvgHandle;
 use node::{NodeResult, NodeTrait, RsvgNode};
-use parsers::{self, parse, Parse};
+use parsers::{self, Parse, ParseValue};
 use property_bag::PropertyBag;
 use rect::IRect;
 use surface_utils::{
@@ -75,7 +75,7 @@ impl NodeTrait for Composite {
                 Attribute::In2 => {
                     self.in2.replace(Some(Input::parse(Attribute::In2, value)?));
                 }
-                Attribute::Operator => self.operator.set(parse("operator", value, ())?),
+                Attribute::Operator => self.operator.set(attr.parse(value, ())?),
                 Attribute::K1 => self.k1.set(
                     parsers::number(value).map_err(|err| NodeError::attribute_error(attr, err))?,
                 ),
diff --git a/rsvg_internals/src/filters/image.rs b/rsvg_internals/src/filters/image.rs
index ada5122d..a730414e 100644
--- a/rsvg_internals/src/filters/image.rs
+++ b/rsvg_internals/src/filters/image.rs
@@ -11,7 +11,7 @@ use drawing_ctx::DrawingCtx;
 use error::{NodeError, RenderingError};
 use handle::{self, RsvgHandle};
 use node::{CascadedValues, NodeResult, NodeTrait, RsvgNode};
-use parsers::{parse, ParseError};
+use parsers::{ParseError, ParseValue};
 use property_bag::PropertyBag;
 use rect::IRect;
 use surface_utils::shared_surface::{SharedImageSurface, SurfaceType};
@@ -197,9 +197,7 @@ impl NodeTrait for Image {
 
         for (attr, value) in pbag.iter() {
             match attr {
-                Attribute::PreserveAspectRatio => {
-                    self.aspect.set(parse("preserveAspectRatio", value, ())?)
-                }
+                Attribute::PreserveAspectRatio => self.aspect.set(attr.parse(value, ())?),
 
                 // "path" is used by some older Adobe Illustrator versions
                 Attribute::XlinkHref | Attribute::Path => self.set_href(attr, value)?,
diff --git a/rsvg_internals/src/filters/mod.rs b/rsvg_internals/src/filters/mod.rs
index fa17c52f..ab845c9a 100644
--- a/rsvg_internals/src/filters/mod.rs
+++ b/rsvg_internals/src/filters/mod.rs
@@ -12,7 +12,7 @@ use error::{RenderingError, ValueErrorKind};
 use handle::RsvgHandle;
 use length::{Length, LengthDir, LengthUnit};
 use node::{NodeResult, NodeTrait, NodeType, RsvgNode};
-use parsers::{parse_and_validate, ParseError};
+use parsers::{ParseError, ParseValue};
 use property_bag::PropertyBag;
 use state::{ColorInterpolationFilters, ComputedValues};
 use surface_utils::shared_surface::{SharedImageSurface, SurfaceType};
@@ -147,26 +147,22 @@ impl NodeTrait for Primitive {
 
         for (attr, value) in pbag.iter() {
             match attr {
-                Attribute::X => self.x.set(Some(parse_and_validate(
-                    "x",
+                Attribute::X => self.x.set(Some(attr.parse_and_validate(
                     value,
                     LengthDir::Horizontal,
                     check_units,
                 )?)),
-                Attribute::Y => self.y.set(Some(parse_and_validate(
-                    "y",
+                Attribute::Y => self.y.set(Some(attr.parse_and_validate(
                     value,
                     LengthDir::Vertical,
                     check_units,
                 )?)),
-                Attribute::Width => self.width.set(Some(parse_and_validate(
-                    "width",
+                Attribute::Width => self.width.set(Some(attr.parse_and_validate(
                     value,
                     LengthDir::Horizontal,
                     check_units_and_ensure_nonnegative,
                 )?)),
-                Attribute::Height => self.height.set(Some(parse_and_validate(
-                    "height",
+                Attribute::Height => self.height.set(Some(attr.parse_and_validate(
                     value,
                     LengthDir::Vertical,
                     check_units_and_ensure_nonnegative,
diff --git a/rsvg_internals/src/filters/node.rs b/rsvg_internals/src/filters/node.rs
index dd4eb522..cf002cd1 100644
--- a/rsvg_internals/src/filters/node.rs
+++ b/rsvg_internals/src/filters/node.rs
@@ -7,7 +7,7 @@ use error::ValueErrorKind;
 use handle::RsvgHandle;
 use length::{Length, LengthDir, LengthUnit};
 use node::{NodeResult, NodeTrait, RsvgNode};
-use parsers::{parse, parse_and_validate, Parse, ParseError};
+use parsers::{Parse, ParseError, ParseValue};
 use property_bag::PropertyBag;
 
 /// The <filter> node.
@@ -45,7 +45,7 @@ impl NodeTrait for NodeFilter {
         // Parse filterUnits first as it affects x, y, width, height checks.
         for (attr, value) in pbag.iter() {
             match attr {
-                Attribute::FilterUnits => self.filterunits.set(parse("filterUnits", value, ())?),
+                Attribute::FilterUnits => self.filterunits.set(attr.parse(value, ())?),
                 _ => (),
             }
         }
@@ -70,33 +70,26 @@ impl NodeTrait for NodeFilter {
         // Parse the rest of the attributes.
         for (attr, value) in pbag.iter() {
             match attr {
-                Attribute::X => self.x.set(parse_and_validate(
-                    "x",
+                Attribute::X => self.x.set(attr.parse_and_validate(
                     value,
                     LengthDir::Horizontal,
                     check_units,
                 )?),
-                Attribute::Y => self.y.set(parse_and_validate(
-                    "y",
-                    value,
-                    LengthDir::Vertical,
-                    check_units,
-                )?),
-                Attribute::Width => self.width.set(parse_and_validate(
-                    "width",
+                Attribute::Y => {
+                    self.y
+                        .set(attr.parse_and_validate(value, LengthDir::Vertical, check_units)?)
+                }
+                Attribute::Width => self.width.set(attr.parse_and_validate(
                     value,
                     LengthDir::Horizontal,
                     check_units_and_ensure_nonnegative,
                 )?),
-                Attribute::Height => self.height.set(parse_and_validate(
-                    "height",
+                Attribute::Height => self.height.set(attr.parse_and_validate(
                     value,
                     LengthDir::Vertical,
                     check_units_and_ensure_nonnegative,
                 )?),
-                Attribute::PrimitiveUnits => {
-                    self.primitiveunits.set(parse("primitiveUnits", value, ())?)
-                }
+                Attribute::PrimitiveUnits => self.primitiveunits.set(attr.parse(value, ())?),
                 _ => (),
             }
         }
diff --git a/rsvg_internals/src/gradient.rs b/rsvg_internals/src/gradient.rs
index ae20dc88..fd6af744 100644
--- a/rsvg_internals/src/gradient.rs
+++ b/rsvg_internals/src/gradient.rs
@@ -13,7 +13,7 @@ use handle::RsvgHandle;
 use length::*;
 use node::*;
 use paint_server::PaintSource;
-use parsers::{parse, Parse, ParseError};
+use parsers::{Parse, ParseError, ParseValue};
 use property_bag::PropertyBag;
 use rect::RectangleExt;
 use state::{ComputedValues, StopColor};
@@ -659,18 +659,9 @@ impl NodeTrait for NodeGradient {
         for (attr, value) in pbag.iter() {
             match attr {
                 // Attributes common to linear and radial gradients
-                Attribute::GradientUnits => {
-                    g.common.units = Some(parse("gradientUnits", value, ())?)
-                }
-
-                Attribute::GradientTransform => {
-                    g.common.affine = Some(parse("gradientTransform", value, ())?)
-                }
-
-                Attribute::SpreadMethod => {
-                    g.common.spread = Some(parse("spreadMethod", value, ())?)
-                }
-
+                Attribute::GradientUnits => g.common.units = Some(attr.parse(value, ())?),
+                Attribute::GradientTransform => g.common.affine = Some(attr.parse(value, ())?),
+                Attribute::SpreadMethod => g.common.spread = Some(attr.parse(value, ())?),
                 Attribute::XlinkHref => {
                     g.common.fallback =
                         Some(Fragment::parse(value).attribute(Attribute::XlinkHref)?)
@@ -678,16 +669,16 @@ impl NodeTrait for NodeGradient {
 
                 // Attributes specific to each gradient type.  The defaults mandated by the spec
                 // are in GradientVariant::resolve_from_defaults()
-                Attribute::X1 => x1 = Some(parse("x1", value, LengthDir::Horizontal)?),
-                Attribute::Y1 => y1 = Some(parse("y1", value, LengthDir::Vertical)?),
-                Attribute::X2 => x2 = Some(parse("x2", value, LengthDir::Horizontal)?),
-                Attribute::Y2 => y2 = Some(parse("y2", value, LengthDir::Vertical)?),
-
-                Attribute::Cx => cx = Some(parse("cx", value, LengthDir::Horizontal)?),
-                Attribute::Cy => cy = Some(parse("cy", value, LengthDir::Vertical)?),
-                Attribute::R => r = Some(parse("r", value, LengthDir::Both)?),
-                Attribute::Fx => fx = Some(parse("fx", value, LengthDir::Horizontal)?),
-                Attribute::Fy => fy = Some(parse("fy", value, LengthDir::Vertical)?),
+                Attribute::X1 => x1 = Some(attr.parse(value, LengthDir::Horizontal)?),
+                Attribute::Y1 => y1 = Some(attr.parse(value, LengthDir::Vertical)?),
+                Attribute::X2 => x2 = Some(attr.parse(value, LengthDir::Horizontal)?),
+                Attribute::Y2 => y2 = Some(attr.parse(value, LengthDir::Vertical)?),
+
+                Attribute::Cx => cx = Some(attr.parse(value, LengthDir::Horizontal)?),
+                Attribute::Cy => cy = Some(attr.parse(value, LengthDir::Vertical)?),
+                Attribute::R => r = Some(attr.parse(value, LengthDir::Both)?),
+                Attribute::Fx => fx = Some(attr.parse(value, LengthDir::Horizontal)?),
+                Attribute::Fy => fy = Some(attr.parse(value, LengthDir::Vertical)?),
 
                 _ => (),
             }
diff --git a/rsvg_internals/src/image.rs b/rsvg_internals/src/image.rs
index 602e98ab..faf1cdbd 100644
--- a/rsvg_internals/src/image.rs
+++ b/rsvg_internals/src/image.rs
@@ -13,7 +13,7 @@ use float_eq_cairo::ApproxEqCairo;
 use handle::{self, RsvgHandle};
 use length::*;
 use node::*;
-use parsers::{parse, parse_and_validate};
+use parsers::ParseValue;
 use property_bag::PropertyBag;
 
 pub struct NodeImage {
@@ -51,24 +51,20 @@ impl NodeTrait for NodeImage {
 
         for (attr, value) in pbag.iter() {
             match attr {
-                Attribute::X => self.x.set(parse("x", value, LengthDir::Horizontal)?),
-                Attribute::Y => self.y.set(parse("y", value, LengthDir::Vertical)?),
-                Attribute::Width => self.w.set(parse_and_validate(
-                    "width",
+                Attribute::X => self.x.set(attr.parse(value, LengthDir::Horizontal)?),
+                Attribute::Y => self.y.set(attr.parse(value, LengthDir::Vertical)?),
+                Attribute::Width => self.w.set(attr.parse_and_validate(
                     value,
                     LengthDir::Horizontal,
                     Length::check_nonnegative,
                 )?),
-                Attribute::Height => self.h.set(parse_and_validate(
-                    "height",
+                Attribute::Height => self.h.set(attr.parse_and_validate(
                     value,
                     LengthDir::Vertical,
                     Length::check_nonnegative,
                 )?),
 
-                Attribute::PreserveAspectRatio => {
-                    self.aspect.set(parse("preserveAspectRatio", value, ())?)
-                }
+                Attribute::PreserveAspectRatio => self.aspect.set(attr.parse(value, ())?),
 
                 // "path" is used by some older Adobe Illustrator versions
                 Attribute::XlinkHref | Attribute::Path => {
diff --git a/rsvg_internals/src/marker.rs b/rsvg_internals/src/marker.rs
index 79e690d3..a8d629f9 100644
--- a/rsvg_internals/src/marker.rs
+++ b/rsvg_internals/src/marker.rs
@@ -16,8 +16,7 @@ use handle::RsvgHandle;
 use iri::IRI;
 use length::{Length, LengthDir};
 use node::*;
-use parsers::ParseError;
-use parsers::{parse, parse_and_validate, Parse};
+use parsers::{Parse, ParseError, ParseValue};
 use path_builder::*;
 use property_bag::PropertyBag;
 use state::{ComputedValues, SpecifiedValue, State};
@@ -220,33 +219,29 @@ impl NodeTrait for NodeMarker {
 
         for (attr, value) in pbag.iter() {
             match attr {
-                Attribute::MarkerUnits => self.units.set(parse("markerUnits", value, ())?),
+                Attribute::MarkerUnits => self.units.set(attr.parse(value, ())?),
 
-                Attribute::RefX => self.ref_x.set(parse("refX", value, LengthDir::Horizontal)?),
+                Attribute::RefX => self.ref_x.set(attr.parse(value, LengthDir::Horizontal)?),
 
-                Attribute::RefY => self.ref_y.set(parse("refY", value, LengthDir::Vertical)?),
+                Attribute::RefY => self.ref_y.set(attr.parse(value, LengthDir::Vertical)?),
 
-                Attribute::MarkerWidth => self.width.set(parse_and_validate(
-                    "markerWidth",
+                Attribute::MarkerWidth => self.width.set(attr.parse_and_validate(
                     value,
                     LengthDir::Horizontal,
                     Length::check_nonnegative,
                 )?),
 
-                Attribute::MarkerHeight => self.height.set(parse_and_validate(
-                    "markerHeight",
+                Attribute::MarkerHeight => self.height.set(attr.parse_and_validate(
                     value,
                     LengthDir::Vertical,
                     Length::check_nonnegative,
                 )?),
 
-                Attribute::Orient => self.orient.set(parse("orient", value, ())?),
+                Attribute::Orient => self.orient.set(attr.parse(value, ())?),
 
-                Attribute::PreserveAspectRatio => {
-                    self.aspect.set(parse("preserveAspectRatio", value, ())?)
-                }
+                Attribute::PreserveAspectRatio => self.aspect.set(attr.parse(value, ())?),
 
-                Attribute::ViewBox => self.vbox.set(Some(parse("viewBox", value, ())?)),
+                Attribute::ViewBox => self.vbox.set(Some(attr.parse(value, ())?)),
 
                 _ => (),
             }
diff --git a/rsvg_internals/src/mask.rs b/rsvg_internals/src/mask.rs
index b05a1efb..aaf04382 100644
--- a/rsvg_internals/src/mask.rs
+++ b/rsvg_internals/src/mask.rs
@@ -8,7 +8,7 @@ use error::RenderingError;
 use handle::RsvgHandle;
 use length::{Length, LengthDir};
 use node::{NodeResult, NodeTrait, RsvgNode};
-use parsers::{parse, parse_and_validate, Parse};
+use parsers::{Parse, ParseValue};
 use property_bag::PropertyBag;
 use rect::IRect;
 use state::Opacity;
@@ -237,28 +237,20 @@ impl NodeTrait for NodeMask {
     fn set_atts(&self, _: &RsvgNode, _: *const RsvgHandle, pbag: &PropertyBag<'_>) -> NodeResult {
         for (attr, value) in pbag.iter() {
             match attr {
-                Attribute::X => self.x.set(parse("x", value, LengthDir::Horizontal)?),
-                Attribute::Y => self.y.set(parse("y", value, LengthDir::Vertical)?),
-                Attribute::Width => self.width.set(parse_and_validate(
-                    "width",
+                Attribute::X => self.x.set(attr.parse(value, LengthDir::Horizontal)?),
+                Attribute::Y => self.y.set(attr.parse(value, LengthDir::Vertical)?),
+                Attribute::Width => self.width.set(attr.parse_and_validate(
                     value,
                     LengthDir::Horizontal,
                     Length::check_nonnegative,
                 )?),
-                Attribute::Height => self.height.set(parse_and_validate(
-                    "height",
+                Attribute::Height => self.height.set(attr.parse_and_validate(
                     value,
                     LengthDir::Vertical,
                     Length::check_nonnegative,
                 )?),
-
-                Attribute::MaskUnits => self.units.set(parse("maskUnits", value, ())?),
-
-                Attribute::MaskContentUnits => {
-                    self.content_units
-                        .set(parse("maskContentUnits", value, ())?)
-                }
-
+                Attribute::MaskUnits => self.units.set(attr.parse(value, ())?),
+                Attribute::MaskContentUnits => self.content_units.set(attr.parse(value, ())?),
                 _ => (),
             }
         }
diff --git a/rsvg_internals/src/parsers.rs b/rsvg_internals/src/parsers.rs
index 068eb7d8..d89e8cd6 100644
--- a/rsvg_internals/src/parsers.rs
+++ b/rsvg_internals/src/parsers.rs
@@ -1,6 +1,6 @@
 use cssparser::{BasicParseError, Parser, ParserInput, Token};
 
-use std::str::{self, FromStr};
+use std::str;
 
 use attributes::Attribute;
 use error::{NodeError, ValueErrorKind};
@@ -66,6 +66,54 @@ pub fn finite_f32(n: f32) -> Result<f32, ValueErrorKind> {
     }
 }
 
+pub trait ParseValue<T: Parse<Err = ValueErrorKind>> {
+    /// Parses a `value` string into a type `T`.
+    ///
+    /// Some value types need some extra `data` to be parsed.  This
+    /// corresponds to the `<T as Parse>::Data` associated type.  For
+    /// example, an `Length` has an associated `type Data =
+    /// LengthDir`, so to parse a length value, you could specify
+    /// `LengthDir::Horizontal` for `data`, for example.
+    fn parse(&self, value: &str, data: <T as Parse>::Data) -> Result<T, NodeError>;
+
+    /// Parses a `value` string into a type `T` with an optional validation function.
+    ///
+    /// Some value types need some extra `data` to be parsed.  This
+    /// corresponds to the `<T as Parse>::Data` associated type.  For
+    /// example, an `Length` has an associated `type Data =
+    /// LengthDir`, so to parse a length value, you could specify
+    /// `LengthDir::Horizontal` for `data`, for example.
+    fn parse_and_validate<F: FnOnce(T) -> Result<T, ValueErrorKind>>(
+        &self,
+        value: &str,
+        data: <T as Parse>::Data,
+        validate: F,
+    ) -> Result<T, NodeError>;
+}
+
+impl<T: Parse<Err = ValueErrorKind>> ParseValue<T> for Attribute {
+    fn parse(&self, value: &str, data: <T as Parse>::Data) -> Result<T, NodeError> {
+        let mut input = ParserInput::new(value);
+        let mut parser = Parser::new(&mut input);
+
+        T::parse(&mut parser, data).map_err(|e| NodeError::attribute_error(*self, e))
+    }
+
+    fn parse_and_validate<F: FnOnce(T) -> Result<T, ValueErrorKind>>(
+        &self,
+        value: &str,
+        data: <T as Parse>::Data,
+        validate: F,
+    ) -> Result<T, NodeError> {
+        let mut input = ParserInput::new(value);
+        let mut parser = Parser::new(&mut input);
+
+        T::parse(&mut parser, data)
+            .and_then(validate)
+            .map_err(|e| NodeError::attribute_error(*self, e))
+    }
+}
+
 impl Parse for f64 {
     type Data = ();
     type Err = ValueErrorKind;
@@ -77,49 +125,6 @@ impl Parse for f64 {
     }
 }
 
-/// Parses a `value` string into a type `T`.
-///
-/// Some value types need some extra `data` to be parsed.  This
-/// corresponds to the `<T as Parse>::Data` associated type.  For
-/// example, an `Length` has an associated `type Data =
-/// LengthDir`, so to parse a length value, you could specify
-/// `LengthDir::Horizontal` for `data`, for example.
-pub fn parse<T>(key: &str, value: &str, data: <T as Parse>::Data) -> Result<T, NodeError>
-where
-    T: Parse<Err = ValueErrorKind>,
-{
-    let mut input = ParserInput::new(value);
-    let mut parser = Parser::new(&mut input);
-
-    T::parse(&mut parser, data)
-        .map_err(|e| NodeError::attribute_error(Attribute::from_str(key).unwrap(), e))
-}
-
-/// Parses a `value` string into a type `T` with an optional validation function.
-///
-/// Some value types need some extra `data` to be parsed.  This
-/// corresponds to the `<T as Parse>::Data` associated type.  For
-/// example, an `Length` has an associated `type Data =
-/// LengthDir`, so to parse a length value, you could specify
-/// `LengthDir::Horizontal` for `data`, for example.
-pub fn parse_and_validate<T, F>(
-    key: &str,
-    value: &str,
-    data: <T as Parse>::Data,
-    validate: F,
-) -> Result<T, NodeError>
-where
-    T: Parse<Err = ValueErrorKind>,
-    F: FnOnce(T) -> Result<T, ValueErrorKind>,
-{
-    let mut input = ParserInput::new(value);
-    let mut parser = Parser::new(&mut input);
-
-    T::parse(&mut parser, data)
-        .and_then(validate)
-        .map_err(|e| NodeError::attribute_error(Attribute::from_str(key).unwrap(), e))
-}
-
 // number
 //
 // https://www.w3.org/TR/SVG11/types.html#DataTypeNumber
diff --git a/rsvg_internals/src/pattern.rs b/rsvg_internals/src/pattern.rs
index b2de0bf6..537ce6e5 100644
--- a/rsvg_internals/src/pattern.rs
+++ b/rsvg_internals/src/pattern.rs
@@ -17,7 +17,7 @@ use handle::RsvgHandle;
 use length::*;
 use node::*;
 use paint_server::PaintSource;
-use parsers::{parse, parse_and_validate};
+use parsers::ParseValue;
 use property_bag::PropertyBag;
 use state::ComputedValues;
 use unit_interval::UnitInterval;
@@ -189,33 +189,28 @@ impl NodeTrait for NodePattern {
 
         for (attr, value) in pbag.iter() {
             match attr {
-                Attribute::PatternUnits => p.units = Some(parse("patternUnits", value, ())?),
+                Attribute::PatternUnits => p.units = Some(attr.parse(value, ())?),
 
-                Attribute::PatternContentUnits => {
-                    p.content_units = Some(parse("patternContentUnits", value, ())?)
-                }
+                Attribute::PatternContentUnits => p.content_units = Some(attr.parse(value, ())?),
 
-                Attribute::ViewBox => p.vbox = Some(Some(parse("viewBox", value, ())?)),
+                Attribute::ViewBox => p.vbox = Some(Some(attr.parse(value, ())?)),
 
                 Attribute::PreserveAspectRatio => {
-                    p.preserve_aspect_ratio = Some(parse("preserveAspectRatio", value, ())?)
+                    p.preserve_aspect_ratio = Some(attr.parse(value, ())?)
                 }
 
-                Attribute::PatternTransform => {
-                    p.affine = Some(parse("patternTransform", value, ())?)
-                }
+                Attribute::PatternTransform => p.affine = Some(attr.parse(value, ())?),
 
                 Attribute::XlinkHref => {
                     p.fallback = Some(Fragment::parse(value).attribute(Attribute::XlinkHref)?);
                 }
 
-                Attribute::X => p.x = Some(parse("x", value, LengthDir::Horizontal)?),
+                Attribute::X => p.x = Some(attr.parse(value, LengthDir::Horizontal)?),
 
-                Attribute::Y => p.y = Some(parse("y", value, LengthDir::Vertical)?),
+                Attribute::Y => p.y = Some(attr.parse(value, LengthDir::Vertical)?),
 
                 Attribute::Width => {
-                    p.width = Some(parse_and_validate(
-                        "width",
+                    p.width = Some(attr.parse_and_validate(
                         value,
                         LengthDir::Horizontal,
                         Length::check_nonnegative,
@@ -223,8 +218,7 @@ impl NodeTrait for NodePattern {
                 }
 
                 Attribute::Height => {
-                    p.height = Some(parse_and_validate(
-                        "height",
+                    p.height = Some(attr.parse_and_validate(
                         value,
                         LengthDir::Vertical,
                         Length::check_nonnegative,
diff --git a/rsvg_internals/src/shapes.rs b/rsvg_internals/src/shapes.rs
index bc4fa88c..976ddd9b 100644
--- a/rsvg_internals/src/shapes.rs
+++ b/rsvg_internals/src/shapes.rs
@@ -11,7 +11,7 @@ use handle::RsvgHandle;
 use length::*;
 use marker;
 use node::*;
-use parsers::{parse, parse_and_validate, CssParserExt, Parse};
+use parsers::{CssParserExt, Parse, ParseValue};
 use path_builder::*;
 use path_parser;
 use property_bag::PropertyBag;
@@ -308,10 +308,10 @@ impl NodeTrait for NodeLine {
     fn set_atts(&self, _: &RsvgNode, _: *const RsvgHandle, pbag: &PropertyBag<'_>) -> NodeResult {
         for (attr, value) in pbag.iter() {
             match attr {
-                Attribute::X1 => self.x1.set(parse("x1", value, LengthDir::Horizontal)?),
-                Attribute::Y1 => self.y1.set(parse("y1", value, LengthDir::Vertical)?),
-                Attribute::X2 => self.x2.set(parse("x2", value, LengthDir::Horizontal)?),
-                Attribute::Y2 => self.y2.set(parse("y2", value, LengthDir::Vertical)?),
+                Attribute::X1 => self.x1.set(attr.parse(value, LengthDir::Horizontal)?),
+                Attribute::Y1 => self.y1.set(attr.parse(value, LengthDir::Vertical)?),
+                Attribute::X2 => self.x2.set(attr.parse(value, LengthDir::Horizontal)?),
+                Attribute::Y2 => self.y2.set(attr.parse(value, LengthDir::Vertical)?),
                 _ => (),
             }
         }
@@ -374,24 +374,20 @@ impl NodeTrait for NodeRect {
     fn set_atts(&self, _: &RsvgNode, _: *const RsvgHandle, pbag: &PropertyBag<'_>) -> NodeResult {
         for (attr, value) in pbag.iter() {
             match attr {
-                Attribute::X => self.x.set(parse("x", value, LengthDir::Horizontal)?),
-                Attribute::Y => self.y.set(parse("y", value, LengthDir::Vertical)?),
-                Attribute::Width => self.w.set(parse_and_validate(
-                    "width",
+                Attribute::X => self.x.set(attr.parse(value, LengthDir::Horizontal)?),
+                Attribute::Y => self.y.set(attr.parse(value, LengthDir::Vertical)?),
+                Attribute::Width => self.w.set(attr.parse_and_validate(
                     value,
                     LengthDir::Horizontal,
                     Length::check_nonnegative,
                 )?),
-                Attribute::Height => self.h.set(parse_and_validate(
-                    "height",
+                Attribute::Height => self.h.set(attr.parse_and_validate(
                     value,
                     LengthDir::Vertical,
                     Length::check_nonnegative,
                 )?),
-
                 Attribute::Rx => self.rx.set(
-                    parse_and_validate(
-                        "rx",
+                    attr.parse_and_validate(
                         value,
                         LengthDir::Horizontal,
                         Length::check_nonnegative,
@@ -399,7 +395,7 @@ impl NodeTrait for NodeRect {
                     .map(Some)?,
                 ),
                 Attribute::Ry => self.ry.set(
-                    parse_and_validate("ry", value, LengthDir::Vertical, Length::check_nonnegative)
+                    attr.parse_and_validate(value, LengthDir::Vertical, Length::check_nonnegative)
                         .map(Some)?,
                 ),
 
@@ -578,10 +574,9 @@ impl NodeTrait for NodeCircle {
     fn set_atts(&self, _: &RsvgNode, _: *const RsvgHandle, pbag: &PropertyBag<'_>) -> NodeResult {
         for (attr, value) in pbag.iter() {
             match attr {
-                Attribute::Cx => self.cx.set(parse("cx", value, LengthDir::Horizontal)?),
-                Attribute::Cy => self.cy.set(parse("cy", value, LengthDir::Vertical)?),
-                Attribute::R => self.r.set(parse_and_validate(
-                    "r",
+                Attribute::Cx => self.cx.set(attr.parse(value, LengthDir::Horizontal)?),
+                Attribute::Cy => self.cy.set(attr.parse(value, LengthDir::Vertical)?),
+                Attribute::R => self.r.set(attr.parse_and_validate(
                     value,
                     LengthDir::Both,
                     Length::check_nonnegative,
@@ -635,17 +630,14 @@ impl NodeTrait for NodeEllipse {
     fn set_atts(&self, _: &RsvgNode, _: *const RsvgHandle, pbag: &PropertyBag<'_>) -> NodeResult {
         for (attr, value) in pbag.iter() {
             match attr {
-                Attribute::Cx => self.cx.set(parse("cx", value, LengthDir::Horizontal)?),
-                Attribute::Cy => self.cy.set(parse("cy", value, LengthDir::Vertical)?),
-
-                Attribute::Rx => self.rx.set(parse_and_validate(
-                    "rx",
+                Attribute::Cx => self.cx.set(attr.parse(value, LengthDir::Horizontal)?),
+                Attribute::Cy => self.cy.set(attr.parse(value, LengthDir::Vertical)?),
+                Attribute::Rx => self.rx.set(attr.parse_and_validate(
                     value,
                     LengthDir::Horizontal,
                     Length::check_nonnegative,
                 )?),
-                Attribute::Ry => self.ry.set(parse_and_validate(
-                    "ry",
+                Attribute::Ry => self.ry.set(attr.parse_and_validate(
                     value,
                     LengthDir::Vertical,
                     Length::check_nonnegative,
diff --git a/rsvg_internals/src/stop.rs b/rsvg_internals/src/stop.rs
index f3b070e1..87c9eafd 100644
--- a/rsvg_internals/src/stop.rs
+++ b/rsvg_internals/src/stop.rs
@@ -5,7 +5,7 @@ use error::*;
 use handle::RsvgHandle;
 use length::*;
 use node::*;
-use parsers::parse_and_validate;
+use parsers::ParseValue;
 use property_bag::PropertyBag;
 
 pub struct NodeStop {
@@ -50,7 +50,7 @@ impl NodeTrait for NodeStop {
             match attr {
                 Attribute::Offset => {
                     let length =
-                        parse_and_validate("offset", value, LengthDir::Both, validate_offset)?;
+                        attr.parse_and_validate(value, LengthDir::Both, validate_offset)?;
                     assert!(
                         length.unit == LengthUnit::Default || length.unit == LengthUnit::Percent
                     );
diff --git a/rsvg_internals/src/structure.rs b/rsvg_internals/src/structure.rs
index 865c5d82..be7fc846 100644
--- a/rsvg_internals/src/structure.rs
+++ b/rsvg_internals/src/structure.rs
@@ -12,7 +12,7 @@ use float_eq_cairo::ApproxEqCairo;
 use handle::RsvgHandle;
 use length::*;
 use node::*;
-use parsers::{parse, parse_and_validate, Parse};
+use parsers::{Parse, ParseValue};
 use property_bag::{OwnedPropertyBag, PropertyBag};
 use state::Overflow;
 use viewbox::*;
@@ -164,37 +164,34 @@ impl NodeTrait for NodeSvg {
         for (attr, value) in pbag.iter() {
             match attr {
                 Attribute::PreserveAspectRatio => {
-                    self.preserve_aspect_ratio
-                        .set(parse("preserveAspectRatio", value, ())?)
+                    self.preserve_aspect_ratio.set(attr.parse(value, ())?)
                 }
 
                 Attribute::X => {
                     if is_inner_svg {
-                        self.x.set(parse("x", value, LengthDir::Horizontal)?);
+                        self.x.set(attr.parse(value, LengthDir::Horizontal)?);
                     }
                 }
 
                 Attribute::Y => {
                     if is_inner_svg {
-                        self.y.set(parse("y", value, LengthDir::Vertical)?);
+                        self.y.set(attr.parse(value, LengthDir::Vertical)?);
                     }
                 }
 
-                Attribute::Width => self.w.set(parse_and_validate(
-                    "width",
+                Attribute::Width => self.w.set(attr.parse_and_validate(
                     value,
                     LengthDir::Horizontal,
                     Length::check_nonnegative,
                 )?),
 
-                Attribute::Height => self.h.set(parse_and_validate(
-                    "height",
+                Attribute::Height => self.h.set(attr.parse_and_validate(
                     value,
                     LengthDir::Vertical,
                     Length::check_nonnegative,
                 )?),
 
-                Attribute::ViewBox => self.vbox.set(parse("viewBox", value, ()).map(Some)?),
+                Attribute::ViewBox => self.vbox.set(attr.parse(value, ()).map(Some)?),
 
                 _ => (),
             }
@@ -276,12 +273,11 @@ impl NodeTrait for NodeUse {
                         Some(Fragment::parse(value).attribute(Attribute::XlinkHref)?)
                 }
 
-                Attribute::X => self.x.set(parse("x", value, LengthDir::Horizontal)?),
-                Attribute::Y => self.y.set(parse("y", value, LengthDir::Vertical)?),
+                Attribute::X => self.x.set(attr.parse(value, LengthDir::Horizontal)?),
+                Attribute::Y => self.y.set(attr.parse(value, LengthDir::Vertical)?),
 
                 Attribute::Width => self.w.set(
-                    parse_and_validate(
-                        "width",
+                    attr.parse_and_validate(
                         value,
                         LengthDir::Horizontal,
                         Length::check_nonnegative,
@@ -289,13 +285,8 @@ impl NodeTrait for NodeUse {
                     .map(Some)?,
                 ),
                 Attribute::Height => self.h.set(
-                    parse_and_validate(
-                        "height",
-                        value,
-                        LengthDir::Vertical,
-                        Length::check_nonnegative,
-                    )
-                    .map(Some)?,
+                    attr.parse_and_validate(value, LengthDir::Vertical, Length::check_nonnegative)
+                        .map(Some)?,
                 ),
 
                 _ => (),
@@ -442,11 +433,10 @@ impl NodeTrait for NodeSymbol {
         for (attr, value) in pbag.iter() {
             match attr {
                 Attribute::PreserveAspectRatio => {
-                    self.preserve_aspect_ratio
-                        .set(parse("preserveAspectRatio", value, ())?)
+                    self.preserve_aspect_ratio.set(attr.parse(value, ())?)
                 }
 
-                Attribute::ViewBox => self.vbox.set(parse("viewBox", value, ()).map(Some)?),
+                Attribute::ViewBox => self.vbox.set(attr.parse(value, ()).map(Some)?),
 
                 _ => (),
             }
diff --git a/rsvg_internals/src/text.rs b/rsvg_internals/src/text.rs
index 6d776848..b2604888 100644
--- a/rsvg_internals/src/text.rs
+++ b/rsvg_internals/src/text.rs
@@ -9,7 +9,7 @@ use font_props::FontWeightSpec;
 use handle::RsvgHandle;
 use length::*;
 use node::{CascadedValues, NodeResult, NodeTrait, NodeType, RsvgNode};
-use parsers::parse;
+use parsers::ParseValue;
 use property_bag::PropertyBag;
 use space::{xml_space_normalize, NormalizeDefault, XmlSpaceNormalize};
 use state::{
@@ -451,14 +451,14 @@ impl NodeTrait for NodeText {
     fn set_atts(&self, _: &RsvgNode, _: *const RsvgHandle, pbag: &PropertyBag<'_>) -> NodeResult {
         for (attr, value) in pbag.iter() {
             match attr {
-                Attribute::X => self.x.set(parse("x", value, LengthDir::Horizontal)?),
-                Attribute::Y => self.y.set(parse("y", value, LengthDir::Vertical)?),
+                Attribute::X => self.x.set(attr.parse(value, LengthDir::Horizontal)?),
+                Attribute::Y => self.y.set(attr.parse(value, LengthDir::Vertical)?),
                 Attribute::Dx => self
                     .dx
-                    .set(parse("dx", value, LengthDir::Horizontal).map(Some)?),
+                    .set(attr.parse(value, LengthDir::Horizontal).map(Some)?),
                 Attribute::Dy => self
                     .dy
-                    .set(parse("dy", value, LengthDir::Vertical).map(Some)?),
+                    .set(attr.parse(value, LengthDir::Vertical).map(Some)?),
                 _ => (),
             }
         }
@@ -634,16 +634,16 @@ impl NodeTrait for NodeTSpan {
             match attr {
                 Attribute::X => self
                     .x
-                    .set(parse("x", value, LengthDir::Horizontal).map(Some)?),
+                    .set(attr.parse(value, LengthDir::Horizontal).map(Some)?),
                 Attribute::Y => self
                     .y
-                    .set(parse("y", value, LengthDir::Vertical).map(Some)?),
+                    .set(attr.parse(value, LengthDir::Vertical).map(Some)?),
                 Attribute::Dx => self
                     .dx
-                    .set(parse("dx", value, LengthDir::Horizontal).map(Some)?),
+                    .set(attr.parse(value, LengthDir::Horizontal).map(Some)?),
                 Attribute::Dy => self
                     .dy
-                    .set(parse("dy", value, LengthDir::Vertical).map(Some)?),
+                    .set(attr.parse(value, LengthDir::Vertical).map(Some)?),
                 _ => (),
             }
         }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]