commit ea072ce45022c14fd5c125d0cafc9f22f9a14449
parent 4beb783c4b09dcc3c89a426cce2c54b301108152
Author: Joël Lupien <jojolepromain@gmail.com>
Date: Mon, 25 May 2020 08:21:57 -0400
Merge pull request #1 from Vanille-N/master
Add macros
Diffstat:
2 files changed, 154 insertions(+), 0 deletions(-)
diff --git a/src/lib.rs b/src/lib.rs
@@ -168,3 +168,27 @@ impl<B: PartialOrd, O> LowerPartialFunctionBuilder<B, O> {
LowerPartialFunction { funcs: self.funcs }
}
}
+
+/// More convenient syntax to create a partial function
+#[macro_export]
+macro_rules! partfn {
+ ( $( [$start:expr, $end:expr]: $var:ident -> $f:expr,)* ) => {
+ {
+ let mut func = PartialFunction::new();
+ $( func = func.with($start, $end, Box::new(|$var| $f)); )*
+ func.build()
+ }
+ };
+}
+
+/// More convenient syntax to create a lower partial function
+#[macro_export]
+macro_rules! lowpartfn {
+ ( $( [$bound:expr]: $var:ident -> $f:expr,)* ) => {
+ {
+ let mut func = LowerPartialFunction::new();
+ $( func = func.with($bound, Box::new(|$var| $f)); )*
+ func.build()
+ }
+ };
+}
diff --git a/tests/tests_macro.rs b/tests/tests_macro.rs
@@ -0,0 +1,130 @@
+extern crate partial_function;
+
+// All these tests are the same as those in
+// tests.rs, the only difference is that the
+// macro version is used.
+
+#[cfg(test)]
+#[allow(unused_variables)]
+mod tests {
+ use partial_function::*;
+ #[test]
+ fn single() {
+ let p = partfn! {
+ [0.0, 1.0]: x -> x,
+ };
+ assert_eq!(Some(0.5), p.eval(0.5));
+ }
+ #[test]
+ fn single_start() {
+ let p = partfn! {
+ [0.0, 1.0]: x -> x,
+ };
+ assert_eq!(Some(0.0), p.eval(0.0));
+ }
+ #[test]
+ fn single_ending() {
+ let p = partfn! {
+ [0.0, 1.0]: x -> x,
+ };
+ assert_eq!(Some(1.0), p.eval(1.0));
+ }
+ #[test]
+ fn single_nan() {
+ let p = partfn! {
+ [0.0, 1.0]: x -> x,
+ };
+ assert!(p.eval(999.0).is_none());
+ }
+ #[test]
+ fn dual_start() {
+ let p = partfn! {
+ [1.0, 2.0]: x -> 5.0,
+ [0.0, 1.0]: x -> x,
+ };
+ assert_eq!(Some(5.0), p.eval(1.0));
+ }
+ #[test]
+ fn dual_end() {
+ let p = partfn! {
+ [0.0, 1.0]: x -> x,
+ [1.0, 2.0]: x -> 5.0,
+ };
+ assert_eq!(Some(5.0), p.eval(1.0));
+ }
+ #[test]
+ #[should_panic]
+ fn intersect_start() {
+ partfn! {
+ [0.0, 1.0]: x -> x,
+ [-0.5, 0.5]: x -> 5.0,
+ };
+ }
+ #[test]
+ #[should_panic]
+ fn intersect_end() {
+ partfn! {
+ [0.0, 1.0]: x -> x,
+ [0.5, 2.0]: x -> 5.0,
+ };
+ }
+ #[test]
+ #[should_panic]
+ fn intersect_inner() {
+ partfn! {
+ [0.0, 1.0]: x -> x,
+ [0.4, 0.6]: x -> 5.0,
+ };
+ }
+ #[test]
+ #[should_panic]
+ fn intersect_outer() {
+ partfn! {
+ [0.0, 1.0]: x -> x,
+ [-2.0, 2.0]: x -> 5.0,
+ };
+ }
+ #[test]
+ #[should_panic]
+ fn intersect_same() {
+ partfn! {
+ [0.0, 1.0]: x -> x,
+ [0.0, 1.0]: x -> 5.0,
+ };
+ }
+
+ #[test]
+ fn lower_partial_normal() {
+ let f = lowpartfn! {
+ [0.0]: x -> 1,
+ [1.0]: x -> 2,
+ };
+ assert_eq!(f.eval(-1.0), None);
+ assert_eq!(f.eval(0.0), Some(1));
+ assert_eq!(f.eval(0.5), Some(1));
+ assert_eq!(f.eval(1.0), Some(2));
+ assert_eq!(f.eval(1000.0), Some(2));
+ }
+
+ #[test]
+ fn lower_partial_inverse_insert() {
+ let f = lowpartfn! {
+ [1.0]: x -> 2,
+ [0.0]: x -> 1,
+ };
+ assert_eq!(f.eval(-1.0), None);
+ assert_eq!(f.eval(0.0), Some(1));
+ assert_eq!(f.eval(0.5), Some(1));
+ assert_eq!(f.eval(1.0), Some(2));
+ assert_eq!(f.eval(1000.0), Some(2));
+ }
+
+ #[test]
+ #[should_panic]
+ fn lower_partial_overlap() {
+ let f = lowpartfn! {
+ [0.0]: x -> 1,
+ [0.0]: x -> 2,
+ };
+ }
+}