Skip to main content

consortium_ipc/
transceiver.rs

1// Copyright 2026 Ethan Wu
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// SPDX-License-Identifier: Apache-2.0
16
17//! Typed, multidirectional transceiver built on top of two [`Channel`]s.
18
19use consortium_codec::CodecFor;
20
21use crate::transport::{RecvTransport, SendTransport};
22use crate::{Channel, ChannelError, ReceivedMessage, Rx, Tx};
23
24/// A typed, multidirectional endpoint pairing a send half and a receive half.
25///
26/// The two halves carry independent transport types: the full-duplex
27/// `consortium_ipc_transport_memory::SharedMemoryTransport`
28/// is `split` into a `…Tx` send half and a `…Rx` receive half, and each is the
29/// transport of its respective [`Channel`].
30///
31/// # Type parameters
32///
33/// - `TyTx` / `TyRx` - the sent and received message types
34/// - `TrTx` - send-half transport ([`SendTransport`])
35/// - `TrRx` - receive-half transport ([`RecvTransport`])
36/// - `C`  - codec
37pub struct Transceiver<TyTx, TyRx, TrTx, TrRx, C: CodecFor<TyTx> + CodecFor<TyRx>> {
38    tx: Channel<Tx, TyTx, TrTx, C>,
39    rx: Channel<Rx, TyRx, TrRx, C>,
40}
41
42impl<TyTx, TyRx, TrTx, TrRx, C: CodecFor<TyTx> + CodecFor<TyRx>>
43    Transceiver<TyTx, TyRx, TrTx, TrRx, C>
44{
45    /// Create a new [`Transceiver`] from a send half and a receive half.
46    pub fn new(tx: Channel<Tx, TyTx, TrTx, C>, rx: Channel<Rx, TyRx, TrRx, C>) -> Self {
47        Self { tx, rx }
48    }
49
50    /// Get the send half of the transceiver.
51    pub fn tx(&self) -> &Channel<Tx, TyTx, TrTx, C> {
52        &self.tx
53    }
54
55    /// Get the receive half of the transceiver.
56    pub fn rx(&self) -> &Channel<Rx, TyRx, TrRx, C> {
57        &self.rx
58    }
59
60    /// split into two channels
61    #[allow(clippy::type_complexity)]
62    pub fn split(self) -> (Channel<Tx, TyTx, TrTx, C>, Channel<Rx, TyRx, TrRx, C>) {
63        (self.tx, self.rx)
64    }
65}
66
67impl<TyTx, TyRx, TrTx, TrRx, C> Transceiver<TyTx, TyRx, TrTx, TrRx, C>
68where
69    TrTx: SendTransport,
70    C: CodecFor<TyTx> + CodecFor<TyRx>,
71{
72    /// send message
73    pub async fn send(&mut self, msg: &TyTx) -> Result<(), ChannelError<C, TrTx>> {
74        self.tx.send(msg).await
75    }
76}
77
78impl<TyTx, TyRx, TrTx, TrRx, C> Transceiver<TyTx, TyRx, TrTx, TrRx, C>
79where
80    TrRx: RecvTransport,
81    C: CodecFor<TyTx> + CodecFor<TyRx>,
82{
83    /// receive message
84    pub async fn recv(&mut self) -> Result<ReceivedMessage<'_, TyRx, C>, ChannelError<C, TrRx>> {
85        self.rx.recv().await
86    }
87}