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}