karyon_p2p/protocol/peer_conn.rs
1use std::sync::Arc;
2
3use crate::{
4 peer::Peer,
5 protocol::{ProtocolEvent, ProtocolID},
6 Error, Result,
7};
8
9/// Per-protocol view of a Peer with the protocol id baked in. Built
10/// by karyon and handed to the protocol constructor. Hides the
11/// underlying `proto_id` routing so user code never types it.
12pub struct PeerConn {
13 peer: Arc<Peer>,
14 proto_id: ProtocolID,
15}
16
17impl PeerConn {
18 /// karyon-internal constructor. User code receives a fully-built
19 /// `PeerConn` from the protocol constructor closure.
20 pub(crate) fn new(peer: Arc<Peer>, proto_id: ProtocolID) -> Self {
21 Self { peer, proto_id }
22 }
23
24 /// Send pre-encoded payload bytes to the peer on this protocol.
25 pub async fn send(&self, payload: Vec<u8>) -> Result<()> {
26 self.peer.send(self.proto_id.clone(), payload).await
27 }
28
29 /// Receive the next message bytes. Returns `Err(PeerShutdown)`
30 /// when the peer is closing -- callers can treat that as an
31 /// orderly end of stream.
32 pub async fn recv(&self) -> Result<Vec<u8>> {
33 match self.peer.recv(&self.proto_id).await? {
34 ProtocolEvent::Message(bytes) => Ok(bytes),
35 ProtocolEvent::Shutdown => Err(Error::PeerShutdown),
36 }
37 }
38
39 /// Broadcast pre-encoded bytes to every connected peer on this
40 /// protocol.
41 pub async fn broadcast(&self, payload: Vec<u8>) {
42 self.peer.broadcast(&self.proto_id, payload).await
43 }
44
45 /// Underlying peer handle. Escape hatch for code that needs the
46 /// raw `Arc<Peer>` (peer id, endpoint, lifecycle hooks).
47 pub fn inner(&self) -> &Arc<Peer> {
48 &self.peer
49 }
50}