[librsvg] opacity.rs: Implement an Opacity struct and a parser for it



commit 32477f56bf930e2d2e69edadc16d2f9c76b81c4e
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue May 30 19:43:30 2017 -0500

    opacity.rs: Implement an Opacity struct and a parser for it
    
    This can parse
    
      inherit | <number>

 rust/src/lib.rs     |    1 +
 rust/src/opacity.rs |   89 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 0 deletions(-)
---
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 242b4b3..7dfc25f 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -125,6 +125,7 @@ mod gradient;
 mod length;
 mod marker;
 mod node;
+mod opacity;
 mod paint_server;
 mod pt;
 mod parsers;
diff --git a/rust/src/opacity.rs b/rust/src/opacity.rs
new file mode 100644
index 0000000..51c3bc5
--- /dev/null
+++ b/rust/src/opacity.rs
@@ -0,0 +1,89 @@
+/// Struct to represent an inheritable opacity property
+/// https://www.w3.org/TR/SVG/masking.html#OpacityProperty
+
+use ::cssparser::{Parser, Token, NumericValue};
+
+use std::str::FromStr;
+
+use parsers::ParseError;
+use error::*;
+
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub enum Opacity {
+    Inherit,
+    Specified (f64)
+}
+
+impl FromStr for Opacity {
+    type Err = AttributeError;
+
+    fn from_str (s: &str) -> Result<Opacity, AttributeError> {
+        let mut parser = Parser::new (s);
+
+        let token = parser.next ();
+        let result = match token {
+            Ok (Token::Ident (value)) => {
+                if value == "inherit" {
+                    Ok (Opacity::Inherit)
+                } else {
+                    Err (())
+                }
+            },
+
+            Ok (Token::Number (NumericValue { value, .. })) => {
+                if value < 0.0 {
+                    Ok (Opacity::Specified (0.0))
+                } else if value > 1.0 {
+                    Ok (Opacity::Specified (1.0))
+                } else {
+                    Ok (Opacity::Specified (value as f64))
+                }
+            },
+
+            _ => Err (())
+        };
+
+        result.and_then (|opacity|
+                         parser.expect_exhausted ()
+                         .map (|_| opacity)
+                         .map_err (|_| ()))
+            .map_err (|_| AttributeError::Parse (ParseError::new ("expected 'inherit' or number")))
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use std::str::FromStr;
+
+    #[test]
+    fn parses_inherit () {
+        assert_eq! (Opacity::from_str ("inherit"), Ok (Opacity::Inherit));
+    }
+
+    #[test]
+    fn parses_number () {
+        assert_eq! (Opacity::from_str ("0"),   Ok (Opacity::Specified (0.0)));
+        assert_eq! (Opacity::from_str ("1"),   Ok (Opacity::Specified (1.0)));
+        assert_eq! (Opacity::from_str ("0.5"), Ok (Opacity::Specified (0.5)));
+    }
+
+    #[test]
+    fn parses_out_of_range_number () {
+        assert_eq! (Opacity::from_str ("-10"), Ok (Opacity::Specified (0.0)));
+        assert_eq! (Opacity::from_str ("10"),  Ok (Opacity::Specified (1.0)));
+    }
+
+    #[test]
+    fn errors_on_invalid_input () {
+        assert! (is_parse_error (&Opacity::from_str ("")));
+        assert! (is_parse_error (&Opacity::from_str ("foo")));
+        assert! (is_parse_error (&Opacity::from_str ("-x")));
+    }
+
+    #[test]
+    fn errors_on_extra_input () {
+        assert! (is_parse_error (&Opacity::from_str ("inherit a million dollars")));
+        assert! (is_parse_error (&Opacity::from_str ("0.0foo")));
+    }
+}


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