aboutsummaryrefslogtreecommitdiff
path: root/tests/with_lifetimes.rs
blob: 697fc74eb00585a1357a5eb52f6a0eb9dfe4c263 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#![deny(clippy::pedantic)]
#![deny(clippy::all)]
//! Test for the case that the Functor the Free Monad is based on has lifetime parameters that do not depend on the
//! lifetime of the mapping function in the Functor implementation.

use higher_free_macro::free;
use higher::{Functor, Bind, Apply};

#[derive(Functor, Clone)]
struct WithLifetimes<'a,'b, A>{
    s1 : &'a str,
    s2 : &'b str,
    next : A
}

free!(FreeWithLifetimes<'a,'b,A>, WithLifetimes<'a,'b,FreeWithLifetimes<'a,'b,A>>);

fn lifetime_helper<'a,'b>(s1 : &'a str, s2 : &'b str) -> FreeWithLifetimes<'a, 'b, u32>{
    let fv = FreeWithLifetimes::lift_f(WithLifetimes{ s1, s2, next: 15});
    fv.fmap(|x| x+1)
}

#[test]
fn test_with_lifetimes(){
    let s1 = "First";
    let s2 = "Second";
    let fv = lifetime_helper(s1, s2);
    let s3 = "Third";
    let s4 = "Fourth";
    let fv = fv.bind(|x| FreeWithLifetimes::lift_f(WithLifetimes{ s1: s3, s2: s4, next : x+2}));
    let s5 = "Fifth";
    let s6 = "Sixth";
    let fa = FreeWithLifetimes::lift_f(WithLifetimes{s1: s5, s2: s6, next : (|x| x+3).into()});
    let fv = fv.apply(fa);
    match fv {
        FreeWithLifetimes::Free(v) => {
            assert_eq!(v.s1, s5);
            assert_eq!(v.s2, s6);
            match v.next {
                FreeWithLifetimes::Free(v) => {
                    assert_eq!(v.s1, s1);
                    assert_eq!(v.s2, s2);
                    match v.next {
                        FreeWithLifetimes::Free(v) => {
                            assert_eq!(v.s1, s3);
                            assert_eq!(v.s2, s4);
                            match v.next {
                                FreeWithLifetimes::Free(_) => unreachable!(),
                                FreeWithLifetimes::Pure(a) => {
                                    assert_eq!(a, 21);
                                },
                            }
                        },
                        FreeWithLifetimes::Pure(_) => unreachable!(),
                    }
                },
                FreeWithLifetimes::Pure(_) => unreachable!(),
            }
        },
        FreeWithLifetimes::Pure(_) => unreachable!()
    }
}