[librsvg] unitinterval: add a small struct that holds [0-1] values



commit fe218ba571711962b4e3f4e0d7601e5b93862832
Author: Paolo Borelli <pborelli gnome org>
Date:   Thu Apr 26 23:54:47 2018 +0200

    unitinterval: add a small struct that holds [0-1] values
    
    This will be used to hold opacity values

 Makefile.am                        |  1 +
 rsvg_internals/src/lib.rs          |  1 +
 rsvg_internals/src/unitinterval.rs | 78 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 80 insertions(+)
---
diff --git a/Makefile.am b/Makefile.am
index 8622a28b..f9a8a7a6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -96,6 +96,7 @@ RUST_SRC =                                    \
        rsvg_internals/src/structure.rs         \
        rsvg_internals/src/text.rs              \
        rsvg_internals/src/transform.rs         \
+       rsvg_internals/src/unitinterval.rs      \
        rsvg_internals/src/util.rs              \
        rsvg_internals/src/viewbox.rs           \
        rsvg_internals/src/viewport.rs
diff --git a/rsvg_internals/src/lib.rs b/rsvg_internals/src/lib.rs
index baf2a7a9..b26dcdbc 100644
--- a/rsvg_internals/src/lib.rs
+++ b/rsvg_internals/src/lib.rs
@@ -195,6 +195,7 @@ mod stop;
 mod structure;
 mod text;
 mod transform;
+mod unitinterval;
 mod util;
 mod viewbox;
 mod viewport;
diff --git a/rsvg_internals/src/unitinterval.rs b/rsvg_internals/src/unitinterval.rs
new file mode 100644
index 00000000..24594b9b
--- /dev/null
+++ b/rsvg_internals/src/unitinterval.rs
@@ -0,0 +1,78 @@
+use cssparser;
+use std::str::FromStr;
+
+use error::*;
+use parsers::ParseError;
+
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub struct UnitInterval(pub f64);
+
+impl Default for UnitInterval {
+    fn default() -> UnitInterval {
+        UnitInterval(1.0)
+    }
+}
+
+impl FromStr for UnitInterval {
+    type Err = AttributeError;
+
+    fn from_str(s: &str) -> Result<UnitInterval, AttributeError> {
+        let mut input = cssparser::ParserInput::new(s);
+        let mut parser = cssparser::Parser::new(&mut input);
+
+        let x = f64::from(parser
+            .expect_number()
+            .map_err(|_| AttributeError::Parse(ParseError::new("expected number")))?);
+
+        let cx = if x < 0.0 {
+            0.0
+        } else if x > 1.0 {
+            1.0
+        } else {
+            x
+        };
+
+        Ok(UnitInterval(cx))
+    }
+}
+
+impl From<UnitInterval> for u8 {
+    fn from(val: UnitInterval) -> u8 {
+        let UnitInterval(x) = val;
+        (x * 255.0 + 0.5).floor() as u8
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use std::str::FromStr;
+
+    #[test]
+    fn parses_number() {
+        assert_eq!("0".parse(), Ok(UnitInterval(0.0)));
+        assert_eq!("1".parse(), Ok(UnitInterval(1.0)));
+        assert_eq!("0.5".parse(), Ok(UnitInterval(0.5)));
+    }
+
+    #[test]
+    fn parses_out_of_range_number() {
+        assert_eq!("-10".parse(), Ok(UnitInterval(0.0)));
+        assert_eq!("10".parse(), Ok(UnitInterval(1.0)));
+    }
+
+    #[test]
+    fn errors_on_invalid_input() {
+        assert!(is_parse_error(&UnitInterval::from_str("")));
+        assert!(is_parse_error(&UnitInterval::from_str("foo")));
+        assert!(is_parse_error(&UnitInterval::from_str("-x")));
+        assert!(is_parse_error(&UnitInterval::from_str("0.0foo")));
+    }
+
+    #[test]
+    fn convert() {
+        assert_eq!(u8::from(UnitInterval(0.0)), 0);
+        assert_eq!(u8::from(UnitInterval(0.5)), 128);
+        assert_eq!(u8::from(UnitInterval(1.0)), 255);
+    }
+}


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