wcode_protocol/
backend.rs1use std::time::Duration;
9
10use tokio::sync::broadcast;
11use wcode_harness::actor::SessionHandle;
12use wcode_harness::event::AgentEvent;
13use wcode_harness::protocol::{Request, SessionId};
14
15#[cfg(unix)]
16use crate::client::Client;
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub struct Closed;
22
23impl std::fmt::Display for Closed {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 f.write_str("session is closed")
26 }
27}
28
29impl std::error::Error for Closed {}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
34pub enum AskError {
35 Closed,
37 Timeout,
40}
41
42impl std::fmt::Display for AskError {
43 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44 f.write_str(match self {
45 AskError::Closed => "session is closed",
46 AskError::Timeout => "the ask timed out",
47 })
48 }
49}
50
51impl std::error::Error for AskError {}
52
53#[derive(Clone)]
55pub enum Backend {
56 Local(SessionHandle),
58 #[cfg(unix)]
60 Remote(Client),
61}
62
63impl Backend {
64 pub fn send(&self, request: Request) -> Result<(), Closed> {
66 match self {
67 Backend::Local(handle) => handle.send(request).map_err(|_| Closed),
68 #[cfg(unix)]
69 Backend::Remote(client) => client.send(request),
70 }
71 }
72
73 pub fn send_from(&self, from: SessionId, request: Request) -> Result<(), Closed> {
76 match self {
77 Backend::Local(handle) => handle.send_from(from, request).map_err(|_| Closed),
78 #[cfg(unix)]
79 Backend::Remote(client) => client.send_from(from, request),
80 }
81 }
82
83 pub async fn ask_within(
89 &self,
90 request: Request,
91 dur: Duration,
92 ) -> Result<AgentEvent, AskError> {
93 match self {
94 Backend::Local(handle) => tokio::time::timeout(dur, handle.ask(request))
95 .await
96 .map_err(|_| AskError::Timeout)?
97 .map_err(|_| AskError::Closed),
98 #[cfg(unix)]
99 Backend::Remote(client) => client.ask_within(request, dur).await,
100 }
101 }
102 pub async fn ask(&self, request: Request) -> Result<AgentEvent, Closed> {
104 match self {
105 Backend::Local(handle) => handle.ask(request).await.map_err(|_| Closed),
106 #[cfg(unix)]
107 Backend::Remote(client) => client.ask(request).await,
108 }
109 }
110
111 pub fn subscribe(&self) -> broadcast::Receiver<AgentEvent> {
113 match self {
114 Backend::Local(handle) => handle.subscribe(),
115 #[cfg(unix)]
116 Backend::Remote(client) => client.subscribe(),
117 }
118 }
119}
120
121impl From<SessionHandle> for Backend {
122 fn from(handle: SessionHandle) -> Self {
123 Backend::Local(handle)
124 }
125}
126
127#[cfg(unix)]
128impl From<Client> for Backend {
129 fn from(client: Client) -> Self {
130 Backend::Remote(client)
131 }
132}