[librsvg] parsers::number_optional_number(): New parser



commit 0f77b0d160c4f601821b0f36c8bc2c6bd2ff3592
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue Jun 13 08:40:31 2017 -0500

    parsers::number_optional_number(): New parser
    
    https://www.w3.org/TR/SVG/types.html#DataTypeNumberOptionalNumber

 rust/src/parsers.rs |   56 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 56 insertions(+), 0 deletions(-)
---
diff --git a/rust/src/parsers.rs b/rust/src/parsers.rs
index e56effe..bb6eaf7 100644
--- a/rust/src/parsers.rs
+++ b/rust/src/parsers.rs
@@ -1,3 +1,4 @@
+use ::cssparser::{Parser, Token, BasicParseError};
 use ::nom::{IResult, double, is_alphabetic};
 
 use std::str;
@@ -17,6 +18,12 @@ impl ParseError {
     }
 }
 
+impl<'a> From<BasicParseError<'a>> for ParseError {
+    fn from (_: BasicParseError) -> ParseError {
+        ParseError::new ("parse error")
+    }
+}
+
 /*
 impl<'a> From<IError<&'a [u8]>> for NomError {
     fn from (e: IError<&[u8]>) -> NomError {
@@ -113,6 +120,33 @@ named! (pub coordinate_pair<(f64, f64)>,
                    y: double        >>
                    (x, y)));
 
+// number-optional-number
+//
+// https://www.w3.org/TR/SVG/types.html#DataTypeNumberOptionalNumber
+
+pub fn number_optional_number (s: &str) -> Result <(f64, f64), ParseError> {
+    let mut parser = Parser::new (s);
+
+    let x = parser.expect_number ()? as f64;
+
+    if !parser.is_exhausted () {
+        let position = parser.position ();
+
+        match parser.next ()? {
+            Token::Comma => {},
+            _ => parser.reset (position)
+        };
+
+        let y = parser.expect_number ()? as f64;
+
+        parser.expect_exhausted ()?;
+
+        Ok ((x, y))
+    } else {
+        Ok ((x, x))
+    }
+}
+
 // Parse a list-of-points as for polyline and polygon elements
 // https://www.w3.org/TR/SVG/shapes.html#PointsBNF
 
@@ -206,6 +240,28 @@ mod tests {
     }
 
     #[test]
+    fn parses_number_optional_number () {
+        assert_eq! (number_optional_number ("1, 2"), Ok ((1.0, 2.0)));
+        assert_eq! (number_optional_number ("1 2"),  Ok ((1.0, 2.0)));
+        assert_eq! (number_optional_number ("1"),    Ok ((1.0, 1.0)));
+
+        assert_eq! (number_optional_number ("-1, -2"), Ok ((-1.0, -2.0)));
+        assert_eq! (number_optional_number ("-1 -2"),  Ok ((-1.0, -2.0)));
+        assert_eq! (number_optional_number ("-1"),     Ok ((-1.0, -1.0)));
+    }
+
+    #[test]
+    fn invalid_number_optional_number () {
+        assert! (number_optional_number ("").is_err ());
+        assert! (number_optional_number ("1x").is_err ());
+        assert! (number_optional_number ("x1").is_err ());
+        assert! (number_optional_number ("1 x").is_err ());
+        assert! (number_optional_number ("1 , x").is_err ());
+        assert! (number_optional_number ("1 , 2x").is_err ());
+        assert! (number_optional_number ("1 2 x").is_err ());
+    }
+
+    #[test]
     fn parses_comma_wsp () {
         assert_eq! (comma_wsp (b" , "), IResult::Done (&b""[..], &b" , "[..]));
         assert_eq! (comma_wsp (b","),   IResult::Done (&b""[..], &b","[..]));


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