[librsvg: 50/51] Remove the CssParserExt trait



commit 2781f030f697905347d25a04b58ee0862caadfd4
Author: Federico Mena Quintero <federico gnome org>
Date:   Wed Dec 18 19:17:04 2019 -0600

    Remove the CssParserExt trait
    
    The two extension methods for cssparser::Parser that we had through
    that trait are now these:
    
      expect_finite_number -> impl Parse for f64
      optional_comma -> standalone optional_comma
    
    The first one combines finite_f32 plus f64::from; it makes a lot of
    code simpler, since we don't check for finite numbers all over the
    place.
    
    In addition, there is a temporary ParseToParseError trait and
    implementation for f64, which is used in transform.rs because
    otherwise there's just too much conversion of error values in there.

 rsvg_internals/src/dasharray.rs                  |   4 +-
 rsvg_internals/src/filters/color_matrix.rs       |   6 +-
 rsvg_internals/src/filters/component_transfer.rs |  23 +--
 rsvg_internals/src/filters/composite.rs          |  10 +-
 rsvg_internals/src/filters/convolve_matrix.rs    |   4 +-
 rsvg_internals/src/filters/displacement_map.rs   |   8 +-
 rsvg_internals/src/filters/light/light_source.rs |  40 ++--
 rsvg_internals/src/filters/light/lighting.rs     |  13 +-
 rsvg_internals/src/filters/offset.rs             |   7 +-
 rsvg_internals/src/filters/turbulence.rs         |   2 +-
 rsvg_internals/src/length.rs                     |   3 +-
 rsvg_internals/src/number_list.rs                |   8 +-
 rsvg_internals/src/parsers.rs                    |  77 ++++---
 rsvg_internals/src/shapes.rs                     |  10 +-
 rsvg_internals/src/transform.rs                  | 243 +++++++++--------------
 rsvg_internals/src/unit_interval.rs              |   9 +-
 16 files changed, 190 insertions(+), 277 deletions(-)
---
diff --git a/rsvg_internals/src/dasharray.rs b/rsvg_internals/src/dasharray.rs
index 34d55686..56e726b2 100644
--- a/rsvg_internals/src/dasharray.rs
+++ b/rsvg_internals/src/dasharray.rs
@@ -4,7 +4,7 @@ use cssparser::Parser;
 
 use crate::error::*;
 use crate::length::*;
-use crate::parsers::{CssParserExt, Parse};
+use crate::parsers::{optional_comma, Parse};
 
 #[derive(Debug, PartialEq, Clone)]
 pub enum Dasharray {
@@ -37,7 +37,7 @@ impl Parse for Dasharray {
                 break;
             }
 
-            parser.optional_comma();
+            optional_comma(parser);
         }
 
         Ok(Dasharray::Array(dasharray))
diff --git a/rsvg_internals/src/filters/color_matrix.rs b/rsvg_internals/src/filters/color_matrix.rs
index b5707c0a..1fc313cc 100644
--- a/rsvg_internals/src/filters/color_matrix.rs
+++ b/rsvg_internals/src/filters/color_matrix.rs
@@ -7,7 +7,7 @@ use crate::drawing_ctx::DrawingCtx;
 use crate::error::*;
 use crate::node::{NodeResult, NodeTrait, RsvgNode};
 use crate::number_list::{NumberList, NumberListError, NumberListLength};
-use crate::parsers::{self, Parse, ParseValue};
+use crate::parsers::{Parse, ParseValue};
 use crate::property_bag::PropertyBag;
 use crate::surface_utils::{
     iterators::Pixels, shared_surface::SharedImageSurface, ImageSurfaceDataExt, Pixel,
@@ -104,7 +104,7 @@ impl NodeTrait for FeColorMatrix {
                         matrix
                     }
                     OperationType::Saturate => {
-                        let s = parsers::number(value).attribute(attr.clone())?;
+                        let s: f64 = attr.parse(value)?;
                         if s < 0.0 || s > 1.0 {
                             return Err(ValueErrorKind::value_error("expected value from 0 to 1"))
                                 .attribute(attr);
@@ -120,7 +120,7 @@ impl NodeTrait for FeColorMatrix {
                         )
                     }
                     OperationType::HueRotate => {
-                        let degrees = parsers::number(value).attribute(attr.clone())?;
+                        let degrees: f64 = attr.parse(value)?;
                         let (sin, cos) = degrees.to_radians().sin_cos();
 
                         #[cfg_attr(rustfmt, rustfmt_skip)]
diff --git a/rsvg_internals/src/filters/component_transfer.rs 
b/rsvg_internals/src/filters/component_transfer.rs
index 7b7fa298..459c03a8 100644
--- a/rsvg_internals/src/filters/component_transfer.rs
+++ b/rsvg_internals/src/filters/component_transfer.rs
@@ -8,7 +8,7 @@ use crate::drawing_ctx::DrawingCtx;
 use crate::error::*;
 use crate::node::{NodeResult, NodeTrait, NodeType, RsvgNode};
 use crate::number_list::{NumberList, NumberListError, NumberListLength};
-use crate::parsers::{self, Parse, ParseValue};
+use crate::parsers::{Parse, ParseValue};
 use crate::property_bag::PropertyBag;
 use crate::surface_utils::{
     iterators::Pixels, shared_surface::SharedImageSurface, ImageSurfaceDataExt, Pixel,
@@ -224,21 +224,12 @@ macro_rules! func_x {
                                 ).attribute(attr)?;
                             self.table_values = v;
                         }
-                        expanded_name!(svg "slope") => {
-                            self.slope = parsers::number(value).attribute(attr)?
-                        }
-                        expanded_name!(svg "intercept") => {
-                            self.intercept = parsers::number(value).attribute(attr)?
-                        }
-                        expanded_name!(svg "amplitude") => {
-                            self.amplitude = parsers::number(value).attribute(attr)?
-                        }
-                        expanded_name!(svg "exponent") => {
-                            self.exponent = parsers::number(value).attribute(attr)?
-                        }
-                        expanded_name!(svg "offset") => {
-                            self.offset = parsers::number(value).attribute(attr)?
-                        }
+                        expanded_name!(svg "slope") => self.slope = attr.parse(value)?,
+                        expanded_name!(svg "intercept") => self.intercept = attr.parse(value)?,
+                        expanded_name!(svg "amplitude") => self.amplitude = attr.parse(value)?,
+                        expanded_name!(svg "exponent") => self.exponent = attr.parse(value)?,
+                        expanded_name!(svg "offset") => self.offset = attr.parse(value)?,
+
                         _ => (),
                     }
                 }
diff --git a/rsvg_internals/src/filters/composite.rs b/rsvg_internals/src/filters/composite.rs
index ecdbd60d..ff8facde 100644
--- a/rsvg_internals/src/filters/composite.rs
+++ b/rsvg_internals/src/filters/composite.rs
@@ -5,7 +5,7 @@ use markup5ever::{expanded_name, local_name, namespace_url, ns};
 use crate::drawing_ctx::DrawingCtx;
 use crate::error::*;
 use crate::node::{NodeResult, NodeTrait, RsvgNode};
-use crate::parsers::{self, Parse, ParseValue};
+use crate::parsers::{Parse, ParseValue};
 use crate::property_bag::PropertyBag;
 use crate::rect::IRect;
 use crate::surface_utils::{
@@ -68,10 +68,10 @@ impl NodeTrait for FeComposite {
             match attr.expanded() {
                 expanded_name!(svg "in2") => self.in2 = Some(attr.parse(value)?),
                 expanded_name!(svg "operator") => self.operator = attr.parse(value)?,
-                expanded_name!(svg "k1") => self.k1 = parsers::number(value).attribute(attr)?,
-                expanded_name!(svg "k2") => self.k2 = parsers::number(value).attribute(attr)?,
-                expanded_name!(svg "k3") => self.k3 = parsers::number(value).attribute(attr)?,
-                expanded_name!(svg "k4") => self.k4 = parsers::number(value).attribute(attr)?,
+                expanded_name!(svg "k1") => self.k1 = attr.parse(value)?,
+                expanded_name!(svg "k2") => self.k2 = attr.parse(value)?,
+                expanded_name!(svg "k3") => self.k3 = attr.parse(value)?,
+                expanded_name!(svg "k4") => self.k4 = attr.parse(value)?,
                 _ => (),
             }
         }
diff --git a/rsvg_internals/src/filters/convolve_matrix.rs b/rsvg_internals/src/filters/convolve_matrix.rs
index e036787d..4cd66226 100644
--- a/rsvg_internals/src/filters/convolve_matrix.rs
+++ b/rsvg_internals/src/filters/convolve_matrix.rs
@@ -74,7 +74,7 @@ impl NodeTrait for FeConvolveMatrix {
                 }
                 expanded_name!(svg "divisor") => {
                     self.divisor = Some(
-                        parsers::number(value)
+                        f64::parse_str(value)
                             .and_then(|x| {
                                 if x != 0.0 {
                                     Ok(x)
@@ -85,7 +85,7 @@ impl NodeTrait for FeConvolveMatrix {
                             .attribute(attr)?,
                     )
                 }
-                expanded_name!(svg "bias") => self.bias = parsers::number(value).attribute(attr)?,
+                expanded_name!(svg "bias") => self.bias = attr.parse(value)?,
                 expanded_name!(svg "edgeMode") => self.edge_mode = attr.parse(value)?,
                 expanded_name!(svg "kernelUnitLength") => {
                     self.kernel_unit_length = Some(
diff --git a/rsvg_internals/src/filters/displacement_map.rs b/rsvg_internals/src/filters/displacement_map.rs
index afeadaa7..1f7ea246 100644
--- a/rsvg_internals/src/filters/displacement_map.rs
+++ b/rsvg_internals/src/filters/displacement_map.rs
@@ -5,7 +5,7 @@ use markup5ever::{expanded_name, local_name, namespace_url, ns};
 use crate::drawing_ctx::DrawingCtx;
 use crate::error::*;
 use crate::node::{NodeResult, NodeTrait, RsvgNode};
-use crate::parsers::{self, Parse, ParseValue};
+use crate::parsers::{Parse, ParseValue};
 use crate::property_bag::PropertyBag;
 use crate::surface_utils::{iterators::Pixels, shared_surface::SharedImageSurface};
 
@@ -53,12 +53,12 @@ impl NodeTrait for FeDisplacementMap {
         for (attr, value) in pbag.iter() {
             match attr.expanded() {
                 expanded_name!(svg "in2") => self.in2 = Some(attr.parse(value)?),
-                expanded_name!(svg "scale") => {
-                    self.scale = parsers::number(value).attribute(attr)?
-                }
+                expanded_name!(svg "scale") => self.scale = attr.parse(value)?,
+
                 expanded_name!(svg "xChannelSelector") => {
                     self.x_channel_selector = attr.parse(value)?
                 }
+
                 expanded_name!(svg "yChannelSelector") => {
                     self.y_channel_selector = attr.parse(value)?
                 }
diff --git a/rsvg_internals/src/filters/light/light_source.rs 
b/rsvg_internals/src/filters/light/light_source.rs
index 48612540..45d43070 100644
--- a/rsvg_internals/src/filters/light/light_source.rs
+++ b/rsvg_internals/src/filters/light/light_source.rs
@@ -2,10 +2,9 @@ use cssparser;
 use markup5ever::{expanded_name, local_name, namespace_url, ns};
 use nalgebra::Vector3;
 
-use crate::error::AttributeResultExt;
 use crate::filters::context::FilterContext;
 use crate::node::{NodeResult, NodeTrait, RsvgNode};
-use crate::parsers;
+use crate::parsers::{ParseValue};
 use crate::property_bag::PropertyBag;
 use crate::util::clamp;
 
@@ -107,10 +106,8 @@ impl NodeTrait for FeDistantLight {
     fn set_atts(&mut self, _: Option<&RsvgNode>, pbag: &PropertyBag<'_>) -> NodeResult {
         for (attr, value) in pbag.iter() {
             match attr.expanded() {
-                expanded_name!(svg "azimuth") => self.azimuth = parsers::number(value).attribute(attr)?,
-                expanded_name!(svg "elevation") => {
-                    self.elevation = parsers::number(value).attribute(attr)?
-                }
+                expanded_name!(svg "azimuth") => self.azimuth = attr.parse(value)?,
+                expanded_name!(svg "elevation") => self.elevation = attr.parse(value)?,
                 _ => (),
             }
         }
@@ -141,9 +138,9 @@ impl NodeTrait for FePointLight {
     fn set_atts(&mut self, _: Option<&RsvgNode>, pbag: &PropertyBag<'_>) -> NodeResult {
         for (attr, value) in pbag.iter() {
             match attr.expanded() {
-                expanded_name!(svg "x") => self.x = parsers::number(value).attribute(attr)?,
-                expanded_name!(svg "y") => self.y = parsers::number(value).attribute(attr)?,
-                expanded_name!(svg "z") => self.z = parsers::number(value).attribute(attr)?,
+                expanded_name!(svg "x") => self.x = attr.parse(value)?,
+                expanded_name!(svg "y") => self.y = attr.parse(value)?,
+                expanded_name!(svg "z") => self.z = attr.parse(value)?,
                 _ => (),
             }
         }
@@ -190,24 +187,21 @@ impl NodeTrait for FeSpotLight {
     fn set_atts(&mut self, _: Option<&RsvgNode>, pbag: &PropertyBag<'_>) -> NodeResult {
         for (attr, value) in pbag.iter() {
             match attr.expanded() {
-                expanded_name!(svg "x") => self.x = parsers::number(value).attribute(attr)?,
-                expanded_name!(svg "y") => self.y = parsers::number(value).attribute(attr)?,
-                expanded_name!(svg "z") => self.z = parsers::number(value).attribute(attr)?,
-                expanded_name!(svg "pointsAtX") => {
-                    self.points_at_x = parsers::number(value).attribute(attr)?
-                }
-                expanded_name!(svg "pointsAtY") => {
-                    self.points_at_y = parsers::number(value).attribute(attr)?
-                }
-                expanded_name!(svg "pointsAtZ") => {
-                    self.points_at_z = parsers::number(value).attribute(attr)?
-                }
+                expanded_name!(svg "x") => self.x = attr.parse(value)?,
+                expanded_name!(svg "y") => self.y = attr.parse(value)?,
+                expanded_name!(svg "z") => self.z = attr.parse(value)?,
+                expanded_name!(svg "pointsAtX") => self.points_at_x = attr.parse(value)?,
+                expanded_name!(svg "pointsAtY") => self.points_at_y = attr.parse(value)?,
+                expanded_name!(svg "pointsAtZ") => self.points_at_z = attr.parse(value)?,
+
                 expanded_name!(svg "specularExponent") => {
-                    self.specular_exponent = parsers::number(value).attribute(attr)?
+                    self.specular_exponent = attr.parse(value)?
                 }
+
                 expanded_name!(svg "limitingConeAngle") => {
-                    self.limiting_cone_angle = Some(parsers::number(value).attribute(attr)?)
+                    self.limiting_cone_angle = Some(attr.parse(value)?)
                 }
+
                 _ => (),
             }
         }
diff --git a/rsvg_internals/src/filters/light/lighting.rs b/rsvg_internals/src/filters/light/lighting.rs
index 01e3d855..4356a45a 100644
--- a/rsvg_internals/src/filters/light/lighting.rs
+++ b/rsvg_internals/src/filters/light/lighting.rs
@@ -32,7 +32,7 @@ use crate::filters::{
     PrimitiveWithInput,
 };
 use crate::node::{CascadedValues, NodeResult, NodeTrait, NodeType, RsvgNode};
-use crate::parsers;
+use crate::parsers::{self, Parse, ParseValue};
 use crate::property_bag::PropertyBag;
 use crate::surface_utils::{
     shared_surface::{SharedImageSurface, SurfaceType},
@@ -67,9 +67,8 @@ impl Common {
 
         for (attr, value) in pbag.iter() {
             match attr.expanded() {
-                expanded_name!(svg "surfaceScale") => {
-                    self.surface_scale = parsers::number(value).attribute(attr)?
-                }
+                expanded_name!(svg "surfaceScale") => self.surface_scale = attr.parse(value)?,
+
                 expanded_name!(svg "kernelUnitLength") => {
                     self.kernel_unit_length = Some(
                         parsers::number_optional_number(value)
@@ -117,7 +116,7 @@ impl NodeTrait for FeDiffuseLighting {
         for (attr, value) in pbag.iter() {
             match attr.expanded() {
                 expanded_name!(svg "diffuseConstant") => {
-                    self.diffuse_constant = parsers::number(value)
+                    self.diffuse_constant = f64::parse_str(value)
                         .and_then(|x| {
                             if x >= 0.0 {
                                 Ok(x)
@@ -188,7 +187,7 @@ impl NodeTrait for FeSpecularLighting {
         for (attr, value) in pbag.iter() {
             match attr.expanded() {
                 expanded_name!(svg "specularConstant") => {
-                    self.specular_constant = parsers::number(value)
+                    self.specular_constant = f64::parse_str(value)
                         .and_then(|x| {
                             if x >= 0.0 {
                                 Ok(x)
@@ -201,7 +200,7 @@ impl NodeTrait for FeSpecularLighting {
                         .attribute(attr)?;
                 }
                 expanded_name!(svg "specularExponent") => {
-                    self.specular_exponent = parsers::number(value)
+                    self.specular_exponent = f64::parse_str(value)
                         .and_then(|x| {
                             if x >= 1.0 && x <= 128.0 {
                                 Ok(x)
diff --git a/rsvg_internals/src/filters/offset.rs b/rsvg_internals/src/filters/offset.rs
index 195eca66..76f35931 100644
--- a/rsvg_internals/src/filters/offset.rs
+++ b/rsvg_internals/src/filters/offset.rs
@@ -2,9 +2,8 @@ use cairo::{self, ImageSurface};
 use markup5ever::{expanded_name, local_name, namespace_url, ns};
 
 use crate::drawing_ctx::DrawingCtx;
-use crate::error::AttributeResultExt;
 use crate::node::{NodeResult, NodeTrait, RsvgNode};
-use crate::parsers;
+use crate::parsers::{ParseValue};
 use crate::property_bag::PropertyBag;
 use crate::surface_utils::shared_surface::SharedImageSurface;
 
@@ -38,8 +37,8 @@ impl NodeTrait for FeOffset {
 
         for (attr, value) in pbag.iter() {
             match attr.expanded() {
-                expanded_name!(svg "dx") => self.dx = parsers::number(value).attribute(attr)?,
-                expanded_name!(svg "dy") => self.dy = parsers::number(value).attribute(attr)?,
+                expanded_name!(svg "dx") => self.dx = attr.parse(value)?,
+                expanded_name!(svg "dy") => self.dy = attr.parse(value)?,
                 _ => (),
             }
         }
diff --git a/rsvg_internals/src/filters/turbulence.rs b/rsvg_internals/src/filters/turbulence.rs
index 46e9b4ec..e562f6bd 100644
--- a/rsvg_internals/src/filters/turbulence.rs
+++ b/rsvg_internals/src/filters/turbulence.rs
@@ -80,7 +80,7 @@ impl NodeTrait for FeTurbulence {
                 }
                 // Yes, seed needs to be parsed as a number and then truncated.
                 expanded_name!(svg "seed") => {
-                    self.seed = parsers::number(value)
+                    self.seed = f64::parse_str(value)
                         .map(|x| {
                             clamp(
                                 x.trunc(),
diff --git a/rsvg_internals/src/length.rs b/rsvg_internals/src/length.rs
index dc39da72..53c7fa34 100644
--- a/rsvg_internals/src/length.rs
+++ b/rsvg_internals/src/length.rs
@@ -47,8 +47,7 @@ use std::marker::PhantomData;
 
 use crate::drawing_ctx::ViewParams;
 use crate::error::*;
-use crate::parsers::Parse;
-use crate::parsers::finite_f32;
+use crate::parsers::{finite_f32, Parse};
 use crate::properties::ComputedValues;
 
 /// Units for length values.
diff --git a/rsvg_internals/src/number_list.rs b/rsvg_internals/src/number_list.rs
index aff2895c..c3be1ad1 100644
--- a/rsvg_internals/src/number_list.rs
+++ b/rsvg_internals/src/number_list.rs
@@ -2,7 +2,7 @@
 
 use cssparser::{Parser, ParserInput};
 
-use crate::parsers::CssParserExt;
+use crate::parsers::{optional_comma, Parse};
 
 #[derive(Eq, PartialEq)]
 pub enum NumberListLength {
@@ -36,12 +36,12 @@ impl NumberList {
 
         for i in 0.. {
             if i != 0 {
-                parser.optional_comma();
+                optional_comma(parser);
             }
 
-            v.push(f64::from(parser.expect_finite_number().map_err(|_| {
+            v.push(f64::parse(parser).map_err(|_| {
                 NumberListError::Parse("expected number".to_string())
-            })?));
+            })?);
 
             if let NumberListLength::Exact(l) = length {
                 if i + 1 == l {
diff --git a/rsvg_internals/src/parsers.rs b/rsvg_internals/src/parsers.rs
index 52be282f..96019fe7 100644
--- a/rsvg_internals/src/parsers.rs
+++ b/rsvg_internals/src/parsers.rs
@@ -1,6 +1,6 @@
 //! The `Parse` trait for CSS properties, and utilities for parsers.
 
-use cssparser::{Parser, ParserInput, Token};
+use cssparser::{Parser, ParserInput};
 use markup5ever::QualName;
 
 use std::str;
@@ -29,23 +29,9 @@ pub trait Parse: Sized {
     }
 }
 
-/// Extra utility methods for `cssparser::Parser`.
-pub trait CssParserExt {
-    /// Avoid infinities.
-    fn expect_finite_number(&mut self) -> Result<f32, ValueErrorKind>;
-
-    /// Consumes a comma if it exists, or does nothing.
-    fn optional_comma(&mut self);
-}
-
-impl<'i, 't> CssParserExt for Parser<'i, 't> {
-    fn expect_finite_number(&mut self) -> Result<f32, ValueErrorKind> {
-        finite_f32(self.expect_number()?)
-    }
-
-    fn optional_comma(&mut self) {
-        let _ = self.try_parse(|p| p.expect_comma());
-    }
+/// Consumes a comma if it exists, or does nothing.
+pub fn optional_comma<'i, 't>(parser: &mut Parser<'i, 't>) {
+    let _ = parser.try_parse(|p| p.expect_comma());
 }
 
 pub fn finite_f32(n: f32) -> Result<f32, ValueErrorKind> {
@@ -84,26 +70,41 @@ impl<T: Parse> ParseValue<T> for QualName {
         let mut input = ParserInput::new(value);
         let mut parser = Parser::new(&mut input);
 
-        T::parse(&mut parser).and_then(validate).attribute(self.clone())
+        T::parse(&mut parser)
+            .and_then(validate)
+            .attribute(self.clone())
     }
 }
 
 impl Parse for f64 {
+    /// Avoid infinities, and convert to `f64`.
+    /// https://www.w3.org/TR/SVG11/types.html#DataTypeNumber
     fn parse(parser: &mut Parser<'_, '_>) -> Result<f64, ValueErrorKind> {
-        Ok(f64::from(parser.expect_finite_number().map_err(|_| {
-            ValueErrorKind::parse_error("expected number")
-        })?))
+        parser
+            .expect_number()
+            .map_err(|_| ValueErrorKind::parse_error("parse error"))
+            .and_then(|n| Ok(f64::from(finite_f32(n)?)))
     }
 }
 
-// number
-//
-// https://www.w3.org/TR/SVG11/types.html#DataTypeNumber
-pub fn number(s: &str) -> Result<f64, ValueErrorKind> {
-    let mut input = ParserInput::new(s);
-    let mut parser = Parser::new(&mut input);
+pub trait ParseToParseError: Sized {
+    fn parse_to_parse_error<'i>(parser: &mut Parser<'i, '_>) -> Result<Self, ParseError<'i>>;
+}
 
-    Ok(f64::from(parser.expect_finite_number()?))
+impl ParseToParseError for f64 {
+    fn parse_to_parse_error<'i>(parser: &mut Parser<'i, '_>) -> Result<Self, ParseError<'i>> {
+        let loc = parser.current_source_location();
+        parser
+            .expect_number()
+            .map_err(|e| e.into())
+            .and_then(|n| {
+                if n.is_finite() {
+                    Ok(f64::from(n))
+                } else {
+                    Err(loc.new_custom_error(ValueErrorKind::value_error("expected finite number")))
+                }
+            })
+    }
 }
 
 // number-optional-number
@@ -114,17 +115,12 @@ pub fn number_optional_number(s: &str) -> Result<(f64, f64), ValueErrorKind> {
     let mut input = ParserInput::new(s);
     let mut parser = Parser::new(&mut input);
 
-    let x = f64::from(parser.expect_finite_number()?);
+    let x = f64::parse(&mut parser)?;
 
     if !parser.is_exhausted() {
-        let state = parser.state();
-
-        match *parser.next()? {
-            Token::Comma => {}
-            _ => parser.reset(&state),
-        };
+        optional_comma(&mut parser);
 
-        let y = f64::from(parser.expect_finite_number()?);
+        let y = f64::parse(&mut parser)?;
 
         parser.expect_exhausted()?;
 
@@ -154,12 +150,7 @@ pub fn integer_optional_integer(s: &str) -> Result<(i32, i32), ValueErrorKind> {
     let x = parser.expect_integer()?;
 
     if !parser.is_exhausted() {
-        let state = parser.state();
-
-        match *parser.next()? {
-            Token::Comma => {}
-            _ => parser.reset(&state),
-        };
+        optional_comma(&mut parser);
 
         let y = parser.expect_integer()?;
 
diff --git a/rsvg_internals/src/shapes.rs b/rsvg_internals/src/shapes.rs
index 6656a892..a3da4204 100644
--- a/rsvg_internals/src/shapes.rs
+++ b/rsvg_internals/src/shapes.rs
@@ -12,7 +12,7 @@ use crate::error::*;
 use crate::length::*;
 use crate::marker;
 use crate::node::*;
-use crate::parsers::{CssParserExt, Parse, ParseValue};
+use crate::parsers::{optional_comma, Parse, ParseValue};
 use crate::path_builder::*;
 use crate::path_parser;
 use crate::properties::ComputedValues;
@@ -203,9 +203,9 @@ impl Parse for Points {
         let mut v = Vec::new();
 
         loop {
-            let x = f64::from(parser.expect_finite_number()?);
-            parser.optional_comma();
-            let y = f64::from(parser.expect_finite_number()?);
+            let x = f64::parse(parser)?;
+            optional_comma(parser);
+            let y = f64::parse(parser)?;
 
             v.push((x, y));
 
@@ -215,7 +215,7 @@ impl Parse for Points {
 
             match parser.next_including_whitespace() {
                 Ok(&Token::WhiteSpace(_)) => (),
-                _ => parser.optional_comma(),
+                _ => optional_comma(parser),
             }
         }
 
diff --git a/rsvg_internals/src/transform.rs b/rsvg_internals/src/transform.rs
index 094b4c13..145a3309 100644
--- a/rsvg_internals/src/transform.rs
+++ b/rsvg_internals/src/transform.rs
@@ -4,14 +4,15 @@ use cairo;
 
 use std::f64::consts::*;
 
-use cssparser::{ParseError as CssParseError, Parser, Token};
+use cssparser::{self, Parser, Token};
 
 use crate::error::*;
-use crate::parsers::{finite_f32, CssParserExt, Parse};
+use crate::parsers::{optional_comma, Parse, ParseToParseError};
 
 impl Parse for cairo::Matrix {
     fn parse(parser: &mut Parser<'_, '_>) -> Result<cairo::Matrix, ValueErrorKind> {
-        let matrix = parse_transform_list(parser)?;
+        let matrix =
+            parse_transform_list(parser).map_err(|_| ValueErrorKind::parse_error("parse error"))?;
 
         matrix
             .try_invert()
@@ -24,7 +25,7 @@ impl Parse for cairo::Matrix {
 // Its operataion and grammar are described here:
 // https://www.w3.org/TR/SVG/coords.html#TransformAttribute
 
-fn parse_transform_list(parser: &mut Parser<'_, '_>) -> Result<cairo::Matrix, ValueErrorKind> {
+fn parse_transform_list<'i>(parser: &mut Parser<'i, '_>) -> Result<cairo::Matrix, ParseError<'i>> {
     let mut matrix = cairo::Matrix::identity();
 
     loop {
@@ -35,17 +36,17 @@ fn parse_transform_list(parser: &mut Parser<'_, '_>) -> Result<cairo::Matrix, Va
         let m = parse_transform_command(parser)?;
         matrix = cairo::Matrix::multiply(&m, &matrix);
 
-        parser.optional_comma();
+        optional_comma(parser);
     }
 
     Ok(matrix)
 }
 
-fn make_expected_function_error() -> ValueErrorKind {
-    ValueErrorKind::parse_error("expected matrix|translate|scale|rotate|skewX|skewY")
-}
+fn parse_transform_command<'i>(
+    parser: &mut Parser<'i, '_>,
+) -> Result<cairo::Matrix, ParseError<'i>> {
+    let loc = parser.current_source_location();
 
-fn parse_transform_command(parser: &mut Parser<'_, '_>) -> Result<cairo::Matrix, ValueErrorKind> {
     match parser.next()?.clone() {
         Token::Function(ref name) => parse_transform_function(name, parser),
 
@@ -54,14 +55,16 @@ fn parse_transform_command(parser: &mut Parser<'_, '_>) -> Result<cairo::Matrix,
             parse_transform_function(name, parser)
         }
 
-        _ => Err(make_expected_function_error()),
+        tok => Err(loc.new_unexpected_token_error(tok.clone())),
     }
 }
 
-fn parse_transform_function(
+fn parse_transform_function<'i>(
     name: &str,
-    parser: &mut Parser<'_, '_>,
-) -> Result<cairo::Matrix, ValueErrorKind> {
+    parser: &mut Parser<'i, '_>,
+) -> Result<cairo::Matrix, ParseError<'i>> {
+    let loc = parser.current_source_location();
+
     match name {
         "matrix" => parse_matrix_args(parser),
         "translate" => parse_translate_args(parser),
@@ -69,161 +72,103 @@ fn parse_transform_function(
         "rotate" => parse_rotate_args(parser),
         "skewX" => parse_skewx_args(parser),
         "skewY" => parse_skewy_args(parser),
-        _ => Err(make_expected_function_error()),
+        _ => Err(loc.new_custom_error(ValueErrorKind::parse_error(
+            "expected matrix|translate|scale|rotate|skewX|skewY",
+        ))),
     }
 }
 
-fn parse_matrix_args(parser: &mut Parser<'_, '_>) -> Result<cairo::Matrix, ValueErrorKind> {
-    parser
-        .parse_nested_block(|p| {
-            let xx = p.expect_number()?;
-            p.optional_comma();
+fn parse_matrix_args<'i>(parser: &mut Parser<'i, '_>) -> Result<cairo::Matrix, ParseError<'i>> {
+    parser.parse_nested_block(|p| {
+        let xx = f64::parse_to_parse_error(p)?;
+        optional_comma(p);
 
-            let yx = p.expect_number()?;
-            p.optional_comma();
+        let yx = f64::parse_to_parse_error(p)?;
+        optional_comma(p);
 
-            let xy = p.expect_number()?;
-            p.optional_comma();
+        let xy = f64::parse_to_parse_error(p)?;
+        optional_comma(p);
 
-            let yy = p.expect_number()?;
-            p.optional_comma();
+        let yy = f64::parse_to_parse_error(p)?;
+        optional_comma(p);
 
-            let x0 = p.expect_number()?;
-            p.optional_comma();
+        let x0 = f64::parse_to_parse_error(p)?;
+        optional_comma(p);
 
-            let y0 = p.expect_number()?;
+        let y0 = f64::parse_to_parse_error(p)?;
 
-            Ok((xx, yx, xy, yy, x0, y0))
-        })
-        .map_err(CssParseError::<()>::basic)
-        .map_err(ValueErrorKind::from)
-        .and_then(|(xx, yx, xy, yy, x0, y0)| {
-            let xx = f64::from(finite_f32(xx)?);
-            let yx = f64::from(finite_f32(yx)?);
-            let xy = f64::from(finite_f32(xy)?);
-            let yy = f64::from(finite_f32(yy)?);
-            let x0 = f64::from(finite_f32(x0)?);
-            let y0 = f64::from(finite_f32(y0)?);
-
-            Ok(cairo::Matrix::new(xx, yx, xy, yy, x0, y0))
-        })
+        Ok(cairo::Matrix::new(xx, yx, xy, yy, x0, y0))
+    })
 }
 
-fn parse_translate_args(parser: &mut Parser<'_, '_>) -> Result<cairo::Matrix, ValueErrorKind> {
-    parser
-        .parse_nested_block(|p| {
-            let tx = p.expect_number()?;
-
-            let ty = p
-                .try_parse(|p| -> Result<f32, CssParseError<'_, ()>> {
-                    p.optional_comma();
-                    Ok(p.expect_number()?)
-                })
-                .unwrap_or(0.0);
-
-            Ok((tx, ty))
-        })
-        .map_err(CssParseError::<()>::basic)
-        .map_err(ValueErrorKind::from)
-        .and_then(|(tx, ty)| {
-            let tx = f64::from(finite_f32(tx)?);
-            let ty = f64::from(finite_f32(ty)?);
-
-            Ok(cairo::Matrix::new(1.0, 0.0, 0.0, 1.0, tx, ty))
-        })
+fn parse_translate_args<'i>(parser: &mut Parser<'i, '_>) -> Result<cairo::Matrix, ParseError<'i>> {
+    parser.parse_nested_block(|p| {
+        let tx = f64::parse_to_parse_error(p)?;
+
+        let ty = p
+            .try_parse(|p| {
+                optional_comma(p);
+                f64::parse_to_parse_error(p)
+            })
+            .unwrap_or(0.0);
+
+        Ok(cairo::Matrix::new(1.0, 0.0, 0.0, 1.0, tx, ty))
+    })
 }
 
-fn parse_scale_args(parser: &mut Parser<'_, '_>) -> Result<cairo::Matrix, ValueErrorKind> {
-    parser
-        .parse_nested_block(|p| {
-            let x = p.expect_number()?;
-
-            let y = p
-                .try_parse(|p| -> Result<f32, CssParseError<'_, ()>> {
-                    p.optional_comma();
-                    Ok(p.expect_number()?)
-                })
-                .unwrap_or(x);
-
-            Ok((x, y))
-        })
-        .map_err(CssParseError::<()>::basic)
-        .map_err(ValueErrorKind::from)
-        .and_then(|(x, y)| {
-            let x = f64::from(finite_f32(x)?);
-            let y = f64::from(finite_f32(y)?);
-
-            Ok(cairo::Matrix::new(x, 0.0, 0.0, y, 0.0, 0.0))
-        })
+fn parse_scale_args<'i>(parser: &mut Parser<'i, '_>) -> Result<cairo::Matrix, ParseError<'i>> {
+    parser.parse_nested_block(|p| {
+        let x = f64::parse_to_parse_error(p)?;
+
+        let y = p
+            .try_parse(|p| {
+                optional_comma(p);
+                f64::parse_to_parse_error(p)
+            })
+            .unwrap_or(x);
+
+        Ok(cairo::Matrix::new(x, 0.0, 0.0, y, 0.0, 0.0))
+    })
 }
 
-fn parse_rotate_args(parser: &mut Parser<'_, '_>) -> Result<cairo::Matrix, ValueErrorKind> {
-    parser
-        .parse_nested_block(|p| {
-            let angle = p.expect_number()?;
-
-            let (tx, ty) = p
-                .try_parse(|p| -> Result<_, CssParseError<'_, ()>> {
-                    p.optional_comma();
-                    let tx = p.expect_number()?;
-
-                    p.optional_comma();
-                    let ty = p.expect_number()?;
-
-                    Ok((tx, ty))
-                })
-                .unwrap_or((0.0, 0.0));
-
-            Ok((angle, tx, ty))
-        })
-        .map_err(CssParseError::<()>::basic)
-        .map_err(ValueErrorKind::from)
-        .and_then(|(angle, tx, ty)| {
-            let angle = f64::from(finite_f32(angle)?);
-            let tx = f64::from(finite_f32(tx)?);
-            let ty = f64::from(finite_f32(ty)?);
-
-            let angle = angle * PI / 180.0;
-            let (s, c) = angle.sin_cos();
-
-            let mut m = cairo::Matrix::new(1.0, 0.0, 0.0, 1.0, tx, ty);
-
-            m = cairo::Matrix::multiply(&cairo::Matrix::new(c, s, -s, c, 0.0, 0.0), &m);
-            m = cairo::Matrix::multiply(&cairo::Matrix::new(1.0, 0.0, 0.0, 1.0, -tx, -ty), &m);
-            Ok(m)
-        })
+fn parse_rotate_args<'i>(parser: &mut Parser<'i, '_>) -> Result<cairo::Matrix, ParseError<'i>> {
+    parser.parse_nested_block(|p| {
+        let angle = f64::parse_to_parse_error(p)? * PI / 180.0;
+
+        let (tx, ty) = p
+            .try_parse(|p| -> Result<_, ParseError> {
+                optional_comma(p);
+                let tx = f64::parse_to_parse_error(p)?;
+
+                optional_comma(p);
+                let ty = f64::parse_to_parse_error(p)?;
+
+                Ok((tx, ty))
+            })
+            .unwrap_or((0.0, 0.0));
+
+        let (s, c) = angle.sin_cos();
+
+        let mut m = cairo::Matrix::new(1.0, 0.0, 0.0, 1.0, tx, ty);
+
+        m = cairo::Matrix::multiply(&cairo::Matrix::new(c, s, -s, c, 0.0, 0.0), &m);
+        m = cairo::Matrix::multiply(&cairo::Matrix::new(1.0, 0.0, 0.0, 1.0, -tx, -ty), &m);
+        Ok(m)
+    })
 }
 
-fn parse_skewx_args(parser: &mut Parser<'_, '_>) -> Result<cairo::Matrix, ValueErrorKind> {
-    parser
-        .parse_nested_block(|p| {
-            let a = p.expect_number()?;
-            Ok(a)
-        })
-        .map_err(CssParseError::<()>::basic)
-        .map_err(ValueErrorKind::from)
-        .and_then(|a| {
-            let a = f64::from(finite_f32(a)?);
-
-            let a = a * PI / 180.0;
-            Ok(cairo::Matrix::new(1.0, 0.0, a.tan(), 1.0, 0.0, 0.0))
-        })
+fn parse_skewx_args<'i>(parser: &mut Parser<'i, '_>) -> Result<cairo::Matrix, ParseError<'i>> {
+    parser.parse_nested_block(|p| {
+        let a = f64::parse_to_parse_error(p)? * PI / 180.0;
+        Ok(cairo::Matrix::new(1.0, 0.0, a.tan(), 1.0, 0.0, 0.0))
+    })
 }
 
-fn parse_skewy_args(parser: &mut Parser<'_, '_>) -> Result<cairo::Matrix, ValueErrorKind> {
-    parser
-        .parse_nested_block(|p| {
-            let a = p.expect_number()?;
-            Ok(a)
-        })
-        .map_err(CssParseError::<()>::basic)
-        .map_err(ValueErrorKind::from)
-        .and_then(|a| {
-            let a = f64::from(finite_f32(a)?);
-
-            let a = a * PI / 180.0;
-            Ok(cairo::Matrix::new(1.0, a.tan(), 0.0, 1.0, 0.0, 0.0))
-        })
+fn parse_skewy_args<'i>(parser: &mut Parser<'i, '_>) -> Result<cairo::Matrix, ParseError<'i>> {
+    parser.parse_nested_block(|p| {
+        let a = f64::parse_to_parse_error(p)? * PI / 180.0;
+        Ok(cairo::Matrix::new(1.0, a.tan(), 0.0, 1.0, 0.0, 0.0))
+    })
 }
 
 #[cfg(test)]
diff --git a/rsvg_internals/src/unit_interval.rs b/rsvg_internals/src/unit_interval.rs
index fc24b54b..6b7e9d20 100644
--- a/rsvg_internals/src/unit_interval.rs
+++ b/rsvg_internals/src/unit_interval.rs
@@ -3,7 +3,7 @@
 use cssparser::Parser;
 
 use crate::error::*;
-use crate::parsers::{CssParserExt, Parse};
+use crate::parsers::Parse;
 use crate::util;
 
 #[derive(Debug, Default, Copy, Clone, PartialEq, PartialOrd)]
@@ -17,12 +17,7 @@ impl UnitInterval {
 
 impl Parse for UnitInterval {
     fn parse(parser: &mut Parser<'_, '_>) -> Result<UnitInterval, ValueErrorKind> {
-        let x = f64::from(
-            parser
-                .expect_finite_number()
-                .map_err(|_| ValueErrorKind::parse_error("expected number"))?,
-        );
-
+        let x = f64::parse(parser)?;
         Ok(UnitInterval::clamp(x))
     }
 }


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