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
#![cfg_attr(not(feature = "std"), no_std)]

use std::marker::PhantomData;

use merfolk::{
  interfaces::{Backend, Frontend},
  Call, Reply,
};

use anyhow::Result;

use log::trace;

#[derive(derive_builder::Builder)]
#[builder(pattern = "owned")]
#[cfg_attr(not(feature = "std"), builder(no_std))]
pub struct Duplex<'a, B, FC, FR>
where
  B: Backend + 'a,
  FC: Frontend<Backend = B> + 'a,
  FR: Frontend<Backend = B> + 'a,
{
  #[builder(private, default = "PhantomData")]
  __phantom: PhantomData<&'a B>,

  pub caller: FC,

  pub receiver: FR,
}

impl<'a, B, FC, FR> Duplex<'a, B, FC, FR>
where
  B: Backend + 'a,
  FC: Frontend<Backend = B> + 'a,
  FR: Frontend<Backend = B> + 'a,
{
  pub fn builder() -> DuplexBuilder<'a, B, FC, FR> {
    DuplexBuilder::default()
  }
}

unsafe impl<'a, B, FC, FR> Send for Duplex<'a, B, FC, FR>
where
  B: Backend,
  FC: Frontend<Backend = B>,
  FR: Frontend<Backend = B>,
{
}

impl<'a, B, FC, FR> Frontend for Duplex<'a, B, FC, FR>
where
  B: Backend,
  FC: Frontend<Backend = B>,
  FR: Frontend<Backend = B>,
{
  type Backend = B;

  fn register<T>(&mut self, caller: T) -> Result<()>
  where
    T: Fn(Call<<Self::Backend as Backend>::Intermediate>) -> Result<Reply<<Self::Backend as Backend>::Intermediate>> + 'static + Send + Sync,
  {
    trace!("duplex caller");

    self.caller.register(caller)
  }

  #[allow(clippy::type_complexity)]
  fn receive(&self, call: Call<<Self::Backend as Backend>::Intermediate>) -> Result<Reply<<Self::Backend as Backend>::Intermediate>> {
    trace!("receive call");

    self.receiver.receive(call)
  }
}