[librsvg] parsers.rs: Add parser for angle_degrees()



commit c624f17f1605bbb3319229d7040602e1e07ba4ee
Author: Federico Mena Quintero <federico gnome org>
Date:   Mon Feb 27 10:38:37 2017 -0600

    parsers.rs: Add parser for angle_degrees()

 rust/src/parsers.rs |   50 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 49 insertions(+), 1 deletions(-)
---
diff --git a/rust/src/parsers.rs b/rust/src/parsers.rs
index bda6c36..08f330a 100644
--- a/rust/src/parsers.rs
+++ b/rust/src/parsers.rs
@@ -1,5 +1,6 @@
-use nom::{IResult, is_digit, double, double_s, ErrorKind, space, sp};
+use nom::{IResult, is_digit, double, double_s, ErrorKind, space, sp, is_alphabetic};
 use std::str;
+use std::f64::consts::*;
 
 #[derive(Debug, PartialEq, Eq)]
 pub enum Sign {
@@ -69,6 +70,40 @@ named! (comma_wsp,
                                 opt! (comma),
                                 wsp_opt))));
 
+// angle:
+// https://www.w3.org/TR/SVG/types.html#DataTypeAngle
+//
+// angle ::= number ("deg" | "grad" | "rad")?
+//
+// Returns an f64 angle in degrees
+
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub struct ParseAngleError;
+
+named! (angle<(f64, Option<&[u8]>)>,
+        tuple! (double,
+                opt! (take_while! (is_alphabetic))));
+
+pub fn angle_degrees (s: &str) -> Result <f64, ParseAngleError> {
+    let r = angle (s.as_bytes ()).to_full_result ();
+
+    println! ("took {:?} parsed {:?}", s, r);
+
+    match r {
+        Ok ((value, unit)) => {
+            match unit {
+                Some (b"deg")  => Ok (value),
+                Some (b"grad") => Ok (value * 360.0 / 400.0),
+                Some (b"rad")  => Ok (value * 180.0 / PI),
+                Some (b"")     => Ok (value),
+                _              => Err (ParseAngleError)
+            }
+        },
+
+        _ => Err (ParseAngleError)
+    }
+}
+
 // Parse a viewBox attribute
 // https://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute
 //
@@ -242,4 +277,17 @@ mod tests {
             _ => { panic! ("{:?} should be an invalid list-of-points", result); }
         }
     }
+
+    #[test]
+    fn parses_angle () {
+        assert_eq! (angle_degrees ("0"),        Ok (0.0));
+        assert_eq! (angle_degrees ("15"),       Ok (15.0));
+        assert_eq! (angle_degrees ("180.5deg"), Ok (180.5));
+        assert_eq! (angle_degrees ("1rad"),     Ok (180.0 / PI));
+        assert_eq! (angle_degrees ("-400grad"), Ok (-360.0));
+
+        assert_eq! (angle_degrees (""), Err (ParseAngleError));
+        assert_eq! (angle_degrees ("foo"), Err (ParseAngleError));
+        assert_eq! (angle_degrees ("300foo"), Err (ParseAngleError));
+    }
 }


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