partial_function

[Done] Partial Function library for Rust.
git clone https://git.jojolepro.com/partial_function.git
Log | Files | Refs | README | LICENSE

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:
Msrc/lib.rs | 24++++++++++++++++++++++++
Atests/tests_macro.rs | 130+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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, + }; + } +}