[librsvg: 1/7] parsers::number_list() - New function to replace rsvg_css_parse_number_list()



commit f70d5ea50cb726970cf7b6e5215f09cf2cd37732
Author: Federico Mena Quintero <federico gnome org>
Date:   Sat Jun 17 13:11:31 2017 -0500

    parsers::number_list() - New function to replace rsvg_css_parse_number_list()

 rust/src/parsers.rs |   79 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 79 insertions(+), 0 deletions(-)
---
diff --git a/rust/src/parsers.rs b/rust/src/parsers.rs
index b81f103..b92afeb 100644
--- a/rust/src/parsers.rs
+++ b/rust/src/parsers.rs
@@ -201,6 +201,50 @@ pub fn list_of_points (string: &[u8]) -> Result <Vec<(f64, f64)>, ParseError> {
 named! (pub separated_numbers<Vec<f64>>,
         separated_list! (comma_wsp, double));
 
+// Lists of number values
+
+pub enum ListLength {
+    Exact (usize),
+    Maximum (usize)
+}
+
+#[derive(Debug, PartialEq)]
+pub enum NumberListError {
+    IncorrectNumberOfElements,
+    Parse (ParseError)
+}
+
+fn number_list (s: &str, length: ListLength) -> Result <Vec<f64>, NumberListError> {
+    let n;
+
+    match length {
+        ListLength::Exact (l)   => { assert! (l > 0); n = l; }
+        ListLength::Maximum (l) => { assert! (l > 0); n = l; }
+    }
+
+    let mut parser = Parser::new (s);
+
+    let mut v = Vec::<f64>::with_capacity (n);
+
+    for i in 0..n {
+        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 ());
+        }
+
+        if parser.is_exhausted () {
+            if let ListLength::Maximum (_) = length {
+                break;
+            }
+        }
+    }
+
+    parser.expect_exhausted ().map_err (|_| NumberListError::IncorrectNumberOfElements)?;
+
+    Ok(v)
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -352,4 +396,39 @@ mod tests {
         assert! (angle_degrees ("foo").is_err ());
         assert! (angle_degrees ("300foo").is_err ());
     }
+
+    #[test]
+    fn parses_number_list () {
+        assert_eq! (number_list ("5", ListLength::Exact (1)),
+                    Ok (vec! [5.0]));
+
+        assert_eq! (number_list ("1 2 3 4", ListLength::Exact (4)),
+                    Ok (vec! [1.0, 2.0, 3.0, 4.0]));
+
+        assert_eq! (number_list ("5", ListLength::Maximum (1)),
+                    Ok (vec! [5.0]));
+
+        assert_eq! (number_list ("1.0, -2.5", ListLength::Maximum (2)),
+                    Ok (vec! [1.0, -2.5]));
+
+        assert_eq! (number_list ("5 6", ListLength::Maximum (3)),
+                    Ok (vec! [5.0, 6.0]));
+    }
+
+    #[test]
+    fn errors_on_invalid_number_list () {
+        // empty
+        assert! (number_list ("", ListLength::Exact (1)).is_err ());
+
+        // too many
+        assert! (number_list ("1 2", ListLength::Exact (1)).is_err ());
+        assert! (number_list ("1,2,3", ListLength::Maximum (2)).is_err ());
+
+        // extra token
+        assert! (number_list ("1,", ListLength::Exact (1)).is_err ());
+
+        // too few
+        assert! (number_list ("1", ListLength::Exact (2)).is_err ());
+        assert! (number_list ("1 2", ListLength::Exact (3)).is_err ());
+    }
 }


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