[librsvg: 19/43] Convert NumberList and ViewBox to CssParseError



commit 868547d8c89f604d523d7c42f6923dcb2717d7be
Author: Federico Mena Quintero <federico gnome org>
Date:   Fri Dec 20 12:32:16 2019 -0600

    Convert NumberList and ViewBox to CssParseError

 rsvg_internals/src/filters/color_matrix.rs       | 23 ++++-----
 rsvg_internals/src/filters/component_transfer.rs | 13 ++---
 rsvg_internals/src/filters/convolve_matrix.rs    |  8 +---
 rsvg_internals/src/marker.rs                     |  2 +-
 rsvg_internals/src/number_list.rs                | 61 ++++++++++--------------
 rsvg_internals/src/pattern.rs                    |  2 +-
 rsvg_internals/src/structure.rs                  |  4 +-
 rsvg_internals/src/viewbox.rs                    | 30 ++++++------
 8 files changed, 58 insertions(+), 85 deletions(-)
---
diff --git a/rsvg_internals/src/filters/color_matrix.rs b/rsvg_internals/src/filters/color_matrix.rs
index 1fc313cc..28405e87 100644
--- a/rsvg_internals/src/filters/color_matrix.rs
+++ b/rsvg_internals/src/filters/color_matrix.rs
@@ -6,7 +6,7 @@ use nalgebra::{Matrix3, Matrix4x5, Matrix5, Vector5};
 use crate::drawing_ctx::DrawingCtx;
 use crate::error::*;
 use crate::node::{NodeResult, NodeTrait, RsvgNode};
-use crate::number_list::{NumberList, NumberListError, NumberListLength};
+use crate::number_list::{NumberList, NumberListLength};
 use crate::parsers::{Parse, ParseValue};
 use crate::property_bag::PropertyBag;
 use crate::surface_utils::{
@@ -85,19 +85,11 @@ impl NodeTrait for FeColorMatrix {
                 let new_matrix = match operation_type {
                     OperationType::LuminanceToAlpha => unreachable!(),
                     OperationType::Matrix => {
-                        let NumberList(v) =
-                            NumberList::parse_str(value, NumberListLength::Exact(20))
-                                .map_err(|err| {
-                                    let err_str = match err {
-                                        NumberListError::IncorrectNumberOfElements => {
-                                            "incorrect number of elements: expected 20"
-                                        }
-                                        NumberListError::Parse(ref err) => &err,
-                                    };
-
-                                    ValueErrorKind::parse_error(err_str)
-                                })
-                                .attribute(attr)?;
+                        let NumberList(v) = NumberList::parse_str_to_parse_error(
+                            value,
+                            NumberListLength::Exact(20),
+                        )
+                        .attribute(attr)?;
                         let matrix = Matrix4x5::from_row_slice(&v);
                         let mut matrix = matrix.fixed_resize(0.0);
                         matrix[(4, 4)] = 1.0;
@@ -240,6 +232,7 @@ impl Parse for OperationType {
             "saturate" => OperationType::Saturate,
             "hueRotate" => OperationType::HueRotate,
             "luminanceToAlpha" => OperationType::LuminanceToAlpha,
-        ).map_err(|_| ValueErrorKind::parse_error("parse error"))
+        )
+        .map_err(|_| ValueErrorKind::parse_error("parse error"))
     }
 }
diff --git a/rsvg_internals/src/filters/component_transfer.rs 
b/rsvg_internals/src/filters/component_transfer.rs
index 459c03a8..2aa21b57 100644
--- a/rsvg_internals/src/filters/component_transfer.rs
+++ b/rsvg_internals/src/filters/component_transfer.rs
@@ -7,7 +7,7 @@ use markup5ever::{expanded_name, local_name, namespace_url, ns};
 use crate::drawing_ctx::DrawingCtx;
 use crate::error::*;
 use crate::node::{NodeResult, NodeTrait, NodeType, RsvgNode};
-use crate::number_list::{NumberList, NumberListError, NumberListLength};
+use crate::number_list::{NumberList, NumberListLength};
 use crate::parsers::{Parse, ParseValue};
 use crate::property_bag::PropertyBag;
 use crate::surface_utils::{
@@ -213,15 +213,8 @@ macro_rules! func_x {
                         }
                         expanded_name!(svg "tableValues") => {
                             let NumberList(v) =
-                                NumberList::parse_str(value, NumberListLength::Unbounded).map_err(
-                                    |err| {
-                                        if let NumberListError::Parse(err) = err {
-                                            ValueErrorKind::parse_error(&err)
-                                        } else {
-                                            panic!("unexpected number list error");
-                                        }
-                                    },
-                                ).attribute(attr)?;
+                                NumberList::parse_str_to_parse_error(value, NumberListLength::Unbounded)
+                                .attribute(attr)?;
                             self.table_values = v;
                         }
                         expanded_name!(svg "slope") => self.slope = attr.parse(value)?,
diff --git a/rsvg_internals/src/filters/convolve_matrix.rs b/rsvg_internals/src/filters/convolve_matrix.rs
index 4cd66226..6c2b706f 100644
--- a/rsvg_internals/src/filters/convolve_matrix.rs
+++ b/rsvg_internals/src/filters/convolve_matrix.rs
@@ -6,7 +6,7 @@ use nalgebra::{DMatrix, Dynamic, VecStorage};
 use crate::drawing_ctx::DrawingCtx;
 use crate::error::*;
 use crate::node::{NodeResult, NodeTrait, RsvgNode};
-use crate::number_list::{NumberList, NumberListError, NumberListLength};
+use crate::number_list::{NumberList, NumberListLength};
 use crate::parsers::{self, Parse, ParseValue};
 use crate::property_bag::PropertyBag;
 use crate::rect::IRect;
@@ -163,11 +163,7 @@ impl NodeTrait for FeConvolveMatrix {
 
                 // #352: Parse as an unbounded list rather than exact length to prevent aborts due
                 //       to huge allocation attempts by underlying Vec::with_capacity().
-                let NumberList(v) = NumberList::parse_str(value, NumberListLength::Unbounded)
-                    .map_err(|err| match err {
-                        NumberListError::IncorrectNumberOfElements => unreachable!(),
-                        NumberListError::Parse(ref err) => ValueErrorKind::parse_error(&err),
-                    })
+                let NumberList(v) = NumberList::parse_str_to_parse_error(value, NumberListLength::Unbounded)
                     .attribute(attr.clone())?;
 
                 if v.len() != number_of_elements {
diff --git a/rsvg_internals/src/marker.rs b/rsvg_internals/src/marker.rs
index 0af3ee52..5af9193c 100644
--- a/rsvg_internals/src/marker.rs
+++ b/rsvg_internals/src/marker.rs
@@ -195,7 +195,7 @@ impl NodeTrait for Marker {
                 }
                 expanded_name!(svg "orient") => self.orient = attr.parse(value)?,
                 expanded_name!(svg "preserveAspectRatio") => self.aspect = attr.parse(value)?,
-                expanded_name!(svg "viewBox") => self.vbox = Some(attr.parse(value)?),
+                expanded_name!(svg "viewBox") => self.vbox = Some(attr.parse_to_parse_error(value)?),
                 _ => (),
             }
         }
diff --git a/rsvg_internals/src/number_list.rs b/rsvg_internals/src/number_list.rs
index c3be1ad1..efb6e661 100644
--- a/rsvg_internals/src/number_list.rs
+++ b/rsvg_internals/src/number_list.rs
@@ -2,7 +2,8 @@
 
 use cssparser::{Parser, ParserInput};
 
-use crate::parsers::{optional_comma, Parse};
+use crate::error::*;
+use crate::parsers::{optional_comma, ParseToParseError};
 
 #[derive(Eq, PartialEq)]
 pub enum NumberListLength {
@@ -10,23 +11,17 @@ pub enum NumberListLength {
     Unbounded,
 }
 
-#[derive(Debug, PartialEq)]
-pub enum NumberListError {
-    IncorrectNumberOfElements,
-    Parse(String),
-}
-
 #[derive(Debug, PartialEq)]
 pub struct NumberList(pub Vec<f64>);
 
 impl NumberList {
-    pub fn parse(
-        parser: &mut Parser<'_, '_>,
+    pub fn parse_to_parse_error<'i>(
+        parser: &mut Parser<'i, '_>,
         length: NumberListLength,
-    ) -> Result<NumberList, NumberListError> {
+    ) -> Result<Self, CssParseError<'i>> {
         let mut v = match length {
             NumberListLength::Exact(l) if l > 0 => Vec::<f64>::with_capacity(l),
-            NumberListLength::Exact(_) => unreachable!(),
+            NumberListLength::Exact(_) => unreachable!("NumberListLength::Exact cannot be 0"),
             NumberListLength::Unbounded => Vec::<f64>::new(),
         };
 
@@ -39,9 +34,7 @@ impl NumberList {
                 optional_comma(parser);
             }
 
-            v.push(f64::parse(parser).map_err(|_| {
-                NumberListError::Parse("expected number".to_string())
-            })?);
+            v.push(f64::parse_to_parse_error(parser)?);
 
             if let NumberListLength::Exact(l) = length {
                 if i + 1 == l {
@@ -61,18 +54,16 @@ impl NumberList {
             }
         }
 
-        parser
-            .expect_exhausted()
-            .map_err(|_| NumberListError::IncorrectNumberOfElements)?;
+        parser.expect_exhausted()?;
 
         Ok(NumberList(v))
     }
 
-    pub fn parse_str(s: &str, length: NumberListLength) -> Result<NumberList, NumberListError> {
+    pub fn parse_str_to_parse_error<'i>(s: &'i str, length: NumberListLength) -> Result<NumberList, 
CssParseError<'i>> {
         let mut input = ParserInput::new(s);
         let mut parser = Parser::new(&mut input);
 
-        Self::parse(&mut parser, length).and_then(|r| {
+        Self::parse_to_parse_error(&mut parser, length).and_then(|r| {
             // FIXME: parser.expect_exhausted()?;
             Ok(r)
         })
@@ -86,22 +77,22 @@ mod tests {
     #[test]
     fn parses_number_list() {
         assert_eq!(
-            NumberList::parse_str("5", NumberListLength::Exact(1)),
+            NumberList::parse_str_to_parse_error("5", NumberListLength::Exact(1)),
             Ok(NumberList(vec![5.0]))
         );
 
         assert_eq!(
-            NumberList::parse_str("1 2 3 4", NumberListLength::Exact(4)),
+            NumberList::parse_str_to_parse_error("1 2 3 4", NumberListLength::Exact(4)),
             Ok(NumberList(vec![1.0, 2.0, 3.0, 4.0]))
         );
 
         assert_eq!(
-            NumberList::parse_str("", NumberListLength::Unbounded),
+            NumberList::parse_str_to_parse_error("", NumberListLength::Unbounded),
             Ok(NumberList(vec![]))
         );
 
         assert_eq!(
-            NumberList::parse_str("1, 2, 3.0, 4, 5", NumberListLength::Unbounded),
+            NumberList::parse_str_to_parse_error("1, 2, 3.0, 4, 5", NumberListLength::Unbounded),
             Ok(NumberList(vec![1.0, 2.0, 3.0, 4.0, 5.0]))
         );
     }
@@ -109,25 +100,25 @@ mod tests {
     #[test]
     fn errors_on_invalid_number_list() {
         // empty
-        assert!(NumberList::parse_str("", NumberListLength::Exact(1)).is_err());
+        assert!(NumberList::parse_str_to_parse_error("", NumberListLength::Exact(1)).is_err());
 
         // garbage
-        assert!(NumberList::parse_str("foo", NumberListLength::Exact(1)).is_err());
-        assert!(NumberList::parse_str("1foo", NumberListLength::Exact(2)).is_err());
-        assert!(NumberList::parse_str("1 foo", NumberListLength::Exact(2)).is_err());
-        assert!(NumberList::parse_str("1 foo 2", NumberListLength::Exact(2)).is_err());
-        assert!(NumberList::parse_str("1,foo", NumberListLength::Exact(2)).is_err());
+        assert!(NumberList::parse_str_to_parse_error("foo", NumberListLength::Exact(1)).is_err());
+        assert!(NumberList::parse_str_to_parse_error("1foo", NumberListLength::Exact(2)).is_err());
+        assert!(NumberList::parse_str_to_parse_error("1 foo", NumberListLength::Exact(2)).is_err());
+        assert!(NumberList::parse_str_to_parse_error("1 foo 2", NumberListLength::Exact(2)).is_err());
+        assert!(NumberList::parse_str_to_parse_error("1,foo", NumberListLength::Exact(2)).is_err());
 
         // too many
-        assert!(NumberList::parse_str("1 2", NumberListLength::Exact(1)).is_err());
+        assert!(NumberList::parse_str_to_parse_error("1 2", NumberListLength::Exact(1)).is_err());
 
         // extra token
-        assert!(NumberList::parse_str("1,", NumberListLength::Exact(1)).is_err());
-        assert!(NumberList::parse_str("1,", NumberListLength::Exact(1)).is_err());
-        assert!(NumberList::parse_str("1,", NumberListLength::Unbounded).is_err());
+        assert!(NumberList::parse_str_to_parse_error("1,", NumberListLength::Exact(1)).is_err());
+        assert!(NumberList::parse_str_to_parse_error("1,", NumberListLength::Exact(1)).is_err());
+        assert!(NumberList::parse_str_to_parse_error("1,", NumberListLength::Unbounded).is_err());
 
         // too few
-        assert!(NumberList::parse_str("1", NumberListLength::Exact(2)).is_err());
-        assert!(NumberList::parse_str("1 2", NumberListLength::Exact(3)).is_err());
+        assert!(NumberList::parse_str_to_parse_error("1", NumberListLength::Exact(2)).is_err());
+        assert!(NumberList::parse_str_to_parse_error("1 2", NumberListLength::Exact(3)).is_err());
     }
 }
diff --git a/rsvg_internals/src/pattern.rs b/rsvg_internals/src/pattern.rs
index 5ed5472b..dac6f94c 100644
--- a/rsvg_internals/src/pattern.rs
+++ b/rsvg_internals/src/pattern.rs
@@ -124,7 +124,7 @@ impl NodeTrait for Pattern {
                 expanded_name!(svg "patternContentUnits") => {
                     self.common.content_units = Some(attr.parse(value)?)
                 }
-                expanded_name!(svg "viewBox") => self.common.vbox = Some(Some(attr.parse(value)?)),
+                expanded_name!(svg "viewBox") => self.common.vbox = 
Some(Some(attr.parse_to_parse_error(value)?)),
                 expanded_name!(svg "preserveAspectRatio") => {
                     self.common.preserve_aspect_ratio = Some(attr.parse(value)?)
                 }
diff --git a/rsvg_internals/src/structure.rs b/rsvg_internals/src/structure.rs
index 76145060..a43cfb1e 100644
--- a/rsvg_internals/src/structure.rs
+++ b/rsvg_internals/src/structure.rs
@@ -196,7 +196,7 @@ impl NodeTrait for Svg {
                     self.h =
                         Some(attr.parse_to_parse_error_and_validate(value, 
Length::<Vertical>::check_nonnegative)?)
                 }
-                expanded_name!(svg "viewBox") => self.vbox = attr.parse(value).map(Some)?,
+                expanded_name!(svg "viewBox") => self.vbox = attr.parse_to_parse_error(value).map(Some)?,
                 _ => (),
             }
         }
@@ -429,7 +429,7 @@ impl NodeTrait for Symbol {
                 expanded_name!(svg "preserveAspectRatio") => {
                     self.preserve_aspect_ratio = attr.parse(value)?
                 }
-                expanded_name!(svg "viewBox") => self.vbox = attr.parse(value).map(Some)?,
+                expanded_name!(svg "viewBox") => self.vbox = attr.parse_to_parse_error(value).map(Some)?,
                 _ => (),
             }
         }
diff --git a/rsvg_internals/src/viewbox.rs b/rsvg_internals/src/viewbox.rs
index 31557d0f..360466d9 100644
--- a/rsvg_internals/src/viewbox.rs
+++ b/rsvg_internals/src/viewbox.rs
@@ -4,13 +4,13 @@ use cssparser::Parser;
 
 use crate::error::*;
 use crate::number_list::{NumberList, NumberListLength};
-use crate::parsers::Parse;
+use crate::parsers::ParseToParseError;
 use crate::rect::Rect;
 
 #[derive(Debug, Copy, Clone, PartialEq)]
 pub struct ViewBox(pub Rect);
 
-impl Parse for ViewBox {
+impl ParseToParseError for ViewBox {
     // Parse a viewBox attribute
     // https://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute
     //
@@ -19,18 +19,18 @@ impl Parse for ViewBox {
     // x, y, w, h
     //
     // Where w and h must be nonnegative.
-    fn parse(parser: &mut Parser<'_, '_>) -> Result<ViewBox, ValueErrorKind> {
+    fn parse_to_parse_error<'i>(parser: &mut Parser<'i, '_>) -> Result<ViewBox, CssParseError<'i>> {
+        let loc = parser.current_source_location();
+
         let NumberList(v) =
-            NumberList::parse(parser, NumberListLength::Exact(4)).map_err(|_| {
-                ValueErrorKind::parse_error("string does not match 'x [,] y [,] w [,] h'")
-            })?;
+            NumberList::parse_to_parse_error(parser, NumberListLength::Exact(4))?;
 
         let (x, y, width, height) = (v[0], v[1], v[2], v[3]);
 
         if width >= 0.0 && height >= 0.0 {
             Ok(ViewBox(Rect::new(x, y, x + width, y + height)))
         } else {
-            Err(ValueErrorKind::value_error("width and height must not be negative"))
+            Err(loc.new_custom_error(ValueErrorKind::value_error("width and height must not be negative")))
         }
     }
 }
@@ -42,25 +42,25 @@ mod tests {
     #[test]
     fn parses_valid_viewboxes() {
         assert_eq!(
-            ViewBox::parse_str("  1 2 3 4"),
+            ViewBox::parse_str_to_parse_error("  1 2 3 4"),
             Ok(ViewBox(Rect::new(1.0, 2.0, 4.0, 6.0)))
         );
 
         assert_eq!(
-            ViewBox::parse_str(" -1.5 -2.5e1,34,56e2  "),
+            ViewBox::parse_str_to_parse_error(" -1.5 -2.5e1,34,56e2  "),
             Ok(ViewBox(Rect::new(-1.5, -25.0, 32.5, 5575.0)))
         );
     }
 
     #[test]
     fn parsing_invalid_viewboxes_yields_error() {
-        assert!(is_parse_error(&ViewBox::parse_str("")));
-        assert!(is_value_error(&ViewBox::parse_str(" 1,2,-3,-4 ")));
-        assert!(is_parse_error(&ViewBox::parse_str("qwerasdfzxcv")));
-        assert!(is_parse_error(&ViewBox::parse_str(" 1 2 3 4   5")));
-        assert!(is_parse_error(&ViewBox::parse_str(" 1 2 foo 3 4")));
+        assert!(ViewBox::parse_str_to_parse_error("").is_err());
+        assert!(ViewBox::parse_str_to_parse_error(" 1,2,-3,-4 ").is_err());
+        assert!(ViewBox::parse_str_to_parse_error("qwerasdfzxcv").is_err());
+        assert!(ViewBox::parse_str_to_parse_error(" 1 2 3 4   5").is_err());
+        assert!(ViewBox::parse_str_to_parse_error(" 1 2 foo 3 4").is_err());
 
         // https://gitlab.gnome.org/GNOME/librsvg/issues/344
-        assert!(is_parse_error(&ViewBox::parse_str("0 0 9E80.7")));
+        assert!(ViewBox::parse_str_to_parse_error("0 0 9E80.7").is_err());
     }
 }


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