phantom_protocol/api/
stream.rs1use crate::api::session::SessionCommand;
2use crate::errors::CoreError;
3use crate::transport::multiplexer::{StreamHandle, StreamMessage};
4use bytes::Bytes;
5use tokio::sync::mpsc;
6use tokio::sync::Mutex;
7
8#[cfg_attr(feature = "bindings", derive(uniffi::Object))]
18pub struct PhantomStream {
19 stream_id: u32,
20 tx: mpsc::Sender<SessionCommand>,
22 rx: Mutex<mpsc::Receiver<StreamMessage>>,
24}
25
26impl PhantomStream {
27 pub fn new(handle: StreamHandle, tx: mpsc::Sender<SessionCommand>) -> Self {
28 Self {
29 stream_id: handle.stream_id,
30 tx,
31 rx: Mutex::new(handle.rx),
32 }
33 }
34}
35
36#[cfg_attr(feature = "bindings", uniffi::export(async_runtime = "tokio"))]
37impl PhantomStream {
38 pub fn stream_id(&self) -> u32 {
39 self.stream_id
40 }
41
42 pub async fn send_reliable(&self, data: Vec<u8>) -> Result<(), CoreError> {
43 self.tx
44 .send(SessionCommand::SendStreamReliable {
45 stream_id: self.stream_id,
46 data: Bytes::from(data),
47 })
48 .await
49 .map_err(|_| CoreError::NetworkError("Session closed".into()))
50 }
51
52 pub async fn send_unreliable(&self, data: Vec<u8>) -> Result<(), CoreError> {
53 self.tx
54 .send(SessionCommand::SendStreamUnreliable {
55 stream_id: self.stream_id,
56 data: Bytes::from(data),
57 })
58 .await
59 .map_err(|_| CoreError::NetworkError("Session closed".into()))
60 }
61
62 pub async fn recv(&self) -> Result<Vec<u8>, CoreError> {
63 let mut rx = self.rx.lock().await;
64 loop {
65 match rx.recv().await {
66 Some(StreamMessage::Data(b)) => return Ok(b.to_vec()),
67 Some(StreamMessage::Ack(seq)) => {
68 log::debug!(
69 "PhantomStream {}: received ACK for seq {}",
70 self.stream_id,
71 seq
72 );
73 continue;
80 }
81 Some(StreamMessage::Close) => {
82 return Err(CoreError::NetworkError("Stream closed by peer".into()));
83 }
84 None => {
85 return Err(CoreError::NetworkError("Stream closed locally".into()));
86 }
87 }
88 }
89 }
90
91 pub async fn disconnect(&self) -> Result<(), CoreError> {
97 self.tx
98 .send(SessionCommand::CloseStream {
99 stream_id: self.stream_id,
100 })
101 .await
102 .map_err(|_| CoreError::NetworkError("Session closed".into()))
103 }
104}