[librsvg] RsvgViewBox::from_str(): Implement in terms of parsers::number_list()



commit c41b703beb1a429aeafeec71bbdd00f300a1636d
Author: Federico Mena Quintero <federico gnome org>
Date:   Thu Jul 20 15:10:27 2017 -0500

    RsvgViewBox::from_str(): Implement in terms of parsers::number_list()
    
    The syntax is the same.

 rust/src/parsers.rs |   39 +++++----------------------------------
 rust/src/viewbox.rs |   43 ++++++++++++++++++++++++-------------------
 2 files changed, 29 insertions(+), 53 deletions(-)
---
diff --git a/rust/src/parsers.rs b/rust/src/parsers.rs
index 0b911cc..ac2d8be 100644
--- a/rust/src/parsers.rs
+++ b/rust/src/parsers.rs
@@ -97,29 +97,8 @@ pub fn angle_degrees (s: &str) -> Result <f64, ParseError> {
                 .map_err (|_| ParseError::new ("expected angle")))
 }
 
-// Parse a viewBox attribute
-// https://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute
-//
-// viewBox: double [,] double [,] double [,] double [,]
-//
-// x, y, w, h
-//
-// Where w and h must be nonnegative.
-
-named! (parse_view_box<(f64, f64, f64, f64)>,
-        ws! (do_parse! (x: double    >>
-                        opt! (comma) >>
-                        y: double    >>
-                        opt! (comma) >>
-                        w: double    >>
-                        opt! (comma) >>
-                        h: double    >>
-                        eof! ()      >>
-                        (x, y, w, h))));
-
-pub fn view_box (s: &str) -> Result <(f64, f64, f64, f64), ParseError> {
-    parse_view_box (s.as_bytes ()).to_full_result ()
-        .map_err (|_| ParseError::new ("string does not match 'x [,] y [,] w [,] h'"))
+fn optional_comma (parser: &mut Parser) {
+    let _ = parser.try (|p| p.expect_comma ());
 }
 
 // Coordinate pairs, separated by optional (whitespace-and/or comma)
@@ -223,7 +202,7 @@ pub enum NumberListError {
     Parse (ParseError)
 }
 
-fn number_list (s: &str, length: ListLength) -> Result <Vec<f64>, NumberListError> {
+pub fn number_list (s: &str, length: ListLength) -> Result <Vec<f64>, NumberListError> {
     let n;
 
     match length {
@@ -239,7 +218,7 @@ fn number_list (s: &str, length: ListLength) -> Result <Vec<f64>, NumberListErro
         v.push (parser.expect_number ().map_err (|_| NumberListError::Parse (ParseError::new ("expected 
number")))? as f64);
 
         if i != n - 1 {
-            let _ = parser.try (|p| p.expect_comma ());
+            optional_comma (&mut parser);
         }
 
         if parser.is_exhausted () {
@@ -317,15 +296,6 @@ mod tests {
     use super::*;
 
     #[test]
-    fn parses_view_box () {
-        assert_eq! (view_box ("1 2 3 4"), Ok ((1.0, 2.0, 3.0, 4.0)));
-        assert_eq! (view_box ("1,2,3 4"), Ok ((1.0, 2.0, 3.0, 4.0)));
-        assert_eq! (view_box (" 1,2,3 4 "), Ok ((1.0, 2.0, 3.0, 4.0)));
-
-        assert! (view_box ("1 2 3 4 5").is_err ());
-    }
-
-    #[test]
     fn parses_coordinate_pairs () {
         assert_eq! (coordinate_pair (b"1 2"),    IResult::Done (&b""[..], (1.0, 2.0)));
         assert_eq! (coordinate_pair (b"1-2"),    IResult::Done (&b""[..], (1.0, -2.0)));
@@ -479,6 +449,7 @@ mod tests {
         assert! (number_list ("foo", ListLength::Exact (1)).is_err ());
         assert! (number_list ("1foo", ListLength::Exact (2)).is_err ());
         assert! (number_list ("1 foo", ListLength::Exact (2)).is_err ());
+        assert! (number_list ("1 foo 2", ListLength::Exact (2)).is_err ());
         assert! (number_list ("1,foo", ListLength::Exact (2)).is_err ());
 
         // too many
diff --git a/rust/src/viewbox.rs b/rust/src/viewbox.rs
index 99d248c..3c1806a 100644
--- a/rust/src/viewbox.rs
+++ b/rust/src/viewbox.rs
@@ -5,8 +5,8 @@ use ::glib;
 use std::str::FromStr;
 
 use error::*;
-use parsers::ParseError;
 use parsers;
+use parsers::{ListLength, ParseError};
 
 use self::glib::translate::*;
 
@@ -49,25 +49,28 @@ impl Default for RsvgViewBox {
 impl FromStr for RsvgViewBox {
     type Err = AttributeError;
 
+    // Parse a viewBox attribute
+    // https://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute
+    //
+    // viewBox: double [,] double [,] double [,] double [,]
+    //
+    // x, y, w, h
+    //
+    // Where w and h must be nonnegative.
     fn from_str (s: &str) -> Result<RsvgViewBox, AttributeError> {
-        let result = parsers::view_box (s.trim ());
-
-        match result {
-            Ok ((x, y, w, h)) => {
-                if w >= 0.0 && h >= 0.0 {
-                    Ok (RsvgViewBox::new (cairo::Rectangle { x: x,
-                                                             y: y,
-                                                             width: w,
-                                                             height: h },
-                                          true))
-                } else {
-                    Err (AttributeError::Value ("width and height must not be negative".to_string ()))
-                }
-            },
-
-            Err (e) => {
-                Err (AttributeError::Parse (e))
-            }
+        let v = parsers::number_list (s, ListLength::Exact (4))
+            .map_err (|_| ParseError::new ("string does not match 'x [,] y [,] w [,] h'"))?;
+
+        let (x, y, w, h) = (v[0], v[1], v[2], v[3]);
+
+        if w >= 0.0 && h >= 0.0 {
+            Ok (RsvgViewBox::new (cairo::Rectangle { x: x,
+                                                     y: y,
+                                                     width: w,
+                                                     height: h },
+                                  true))
+        } else {
+            Err (AttributeError::Value ("width and height must not be negative".to_string ()))
         }
     }
 }
@@ -103,5 +106,7 @@ mod tests {
         assert! (is_parse_error (&RsvgViewBox::from_str ("qwerasdfzxcv")));
 
         assert! (is_parse_error (&RsvgViewBox::from_str (" 1 2 3 4   5")));
+
+        assert! (is_parse_error (&RsvgViewBox::from_str (" 1 2 foo 3 4")));
     }
 }


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