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
85
86
use stageleft::quote_type;

use super::{Cluster, ClusterId, ExternalProcess, Location, Process};
use crate::stream::NoOrder;

pub trait CanSend<'a, To: Location<'a>>: Location<'a> {
    type In<T>;
    type Out<T>;

    /// Given the ordering guarantees of the input, determines the strongest possible
    /// ordering guarantees of the output.
    type OutStrongestOrder<InOrder>;

    fn is_demux() -> bool;
    fn tagged_type() -> Option<syn::Type>;
}

impl<'a, P1, P2> CanSend<'a, Process<'a, P2>> for Process<'a, P1> {
    type In<T> = T;
    type Out<T> = T;
    type OutStrongestOrder<InOrder> = InOrder;

    fn is_demux() -> bool {
        false
    }

    fn tagged_type() -> Option<syn::Type> {
        None
    }
}

impl<'a, P1, C2> CanSend<'a, Cluster<'a, C2>> for Process<'a, P1> {
    type In<T> = (ClusterId<C2>, T);
    type Out<T> = T;
    type OutStrongestOrder<InOrder> = InOrder;

    fn is_demux() -> bool {
        true
    }

    fn tagged_type() -> Option<syn::Type> {
        None
    }
}

impl<'a, C1, P2> CanSend<'a, Process<'a, P2>> for Cluster<'a, C1> {
    type In<T> = T;
    type Out<T> = (ClusterId<C1>, T);
    type OutStrongestOrder<InOrder> = NoOrder;

    fn is_demux() -> bool {
        false
    }

    fn tagged_type() -> Option<syn::Type> {
        Some(quote_type::<C1>())
    }
}

impl<'a, C1, C2> CanSend<'a, Cluster<'a, C2>> for Cluster<'a, C1> {
    type In<T> = (ClusterId<C2>, T);
    type Out<T> = (ClusterId<C1>, T);
    type OutStrongestOrder<InOrder> = NoOrder;

    fn is_demux() -> bool {
        true
    }

    fn tagged_type() -> Option<syn::Type> {
        Some(quote_type::<C1>())
    }
}

impl<'a, P1, E2> CanSend<'a, ExternalProcess<'a, E2>> for Process<'a, P1> {
    type In<T> = T;
    type Out<T> = T;
    type OutStrongestOrder<InOrder> = InOrder;

    fn is_demux() -> bool {
        false
    }

    fn tagged_type() -> Option<syn::Type> {
        None
    }
}