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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
mod common;

use common::walker::MockWalker;
use treaty::{
    any::{BorrowedStatic, OwnedStatic, TempBorrowedStatic},
    effect::blocking::Blocking,
    protocol::{
        visitor::{request_hint, ValueProto},
        DynWalker,
    },
    BuildExt as _, Builder as _, Flow,
};

use crate::common::protocol::{hint::MockHintWalker, value::ValueVisitorExt as _};

#[test]
fn value_builder_gives_value_protocol_as_hint() {
    // Create a builder for a i32.
    let mut builder = i32::new_builder();

    // Expect the value builder to hint the value protocol with a owned i32.
    let mut walker = MockHintWalker::<ValueProto<OwnedStatic<i32>, Blocking>>::new();
    walker.expect_hint().once().returning(|mut visitor, ()| {
        // Fulfill the hint by visiting with a i32 value.
        assert_eq!(
            visitor.as_known().visit(OwnedStatic(42)).value(),
            Flow::Done.into()
        );

        // We are done as the walker.
        Flow::Done.into()
    });

    // Request a hint from the i32 builder for what protocol to use.
    assert_eq!(
        request_hint::<Blocking>(builder.as_visitor(), DynWalker(&mut walker)).value(),
        Flow::Done.into()
    );

    // The builder should have the value.
    assert_eq!(builder.build().value().unwrap(), 42);
}

#[test]
fn value_builder_can_use_an_owned_value_or_a_borrowed_value() {
    assert_eq!(
        i32::build({
            let mut walker = MockWalker::<(), ()>::new();
            walker.expect_walk().once().returning(|visitor| {
                visitor.visit_value_and_done(OwnedStatic(1));
                Ok(())
            });
            walker
        })
        .unwrap(),
        1
    );

    assert_eq!(
        i32::build({
            let mut walker = MockWalker::<(), ()>::new();
            walker.expect_walk().once().returning(|visitor| {
                visitor.visit_value_and_done(BorrowedStatic(&2));
                Ok(())
            });
            walker
        })
        .unwrap(),
        2
    );

    assert_eq!(
        i32::build({
            let mut walker = MockWalker::<(), ()>::new();
            walker.expect_walk().once().returning(|visitor| {
                visitor.visit_value_and_done(TempBorrowedStatic(&3));
                Ok(())
            });
            walker
        })
        .unwrap(),
        3
    );
}