Skip to main content

ap_client/
proxy.rs

1//! Proxy client trait and default implementation
2//!
3//! This module provides the `ProxyClient` trait for abstracting proxy communication,
4//! enabling dependency injection and easier testing.
5
6use ap_proxy_client::IncomingMessage;
7#[cfg(feature = "native-websocket")]
8use ap_proxy_client::{ProxyClientConfig, ProxyProtocolClient};
9use ap_proxy_protocol::{IdentityFingerprint, RendezvousCode};
10use async_trait::async_trait;
11use tokio::sync::mpsc;
12
13use crate::error::RemoteClientError;
14
15/// Trait abstracting the proxy client for communication between devices
16#[async_trait]
17pub trait ProxyClient: Send + Sync {
18    /// Connect to the proxy server, returning a receiver for incoming messages
19    async fn connect(
20        &mut self,
21    ) -> Result<mpsc::UnboundedReceiver<IncomingMessage>, RemoteClientError>;
22
23    /// Request a rendezvous code from the proxy server
24    async fn request_rendezvous(&self) -> Result<(), RemoteClientError>;
25
26    /// Request the identity associated with a rendezvous code
27    async fn request_identity(&self, code: RendezvousCode) -> Result<(), RemoteClientError>;
28
29    /// Send a message to a peer by their fingerprint
30    async fn send_to(
31        &self,
32        fingerprint: IdentityFingerprint,
33        data: Vec<u8>,
34    ) -> Result<(), RemoteClientError>;
35
36    /// Disconnect from the proxy server
37    async fn disconnect(&mut self) -> Result<(), RemoteClientError>;
38}
39
40/// Default implementation using ProxyProtocolClient from ap-proxy
41#[cfg(feature = "native-websocket")]
42pub struct DefaultProxyClient {
43    inner: ProxyProtocolClient,
44}
45
46#[cfg(feature = "native-websocket")]
47impl DefaultProxyClient {
48    pub fn new(config: ProxyClientConfig) -> Self {
49        Self {
50            inner: ProxyProtocolClient::new(config),
51        }
52    }
53}
54
55#[cfg(feature = "native-websocket")]
56#[async_trait]
57impl ProxyClient for DefaultProxyClient {
58    async fn connect(
59        &mut self,
60    ) -> Result<mpsc::UnboundedReceiver<IncomingMessage>, RemoteClientError> {
61        self.inner.connect().await.map_err(RemoteClientError::from)
62    }
63
64    async fn request_rendezvous(&self) -> Result<(), RemoteClientError> {
65        self.inner
66            .request_rendezvous()
67            .await
68            .map_err(RemoteClientError::from)
69    }
70
71    async fn request_identity(&self, code: RendezvousCode) -> Result<(), RemoteClientError> {
72        self.inner
73            .request_identity(code)
74            .await
75            .map_err(RemoteClientError::from)
76    }
77
78    async fn send_to(
79        &self,
80        fingerprint: IdentityFingerprint,
81        data: Vec<u8>,
82    ) -> Result<(), RemoteClientError> {
83        self.inner
84            .send_to(fingerprint, data)
85            .await
86            .map_err(RemoteClientError::from)
87    }
88
89    async fn disconnect(&mut self) -> Result<(), RemoteClientError> {
90        self.inner
91            .disconnect()
92            .await
93            .map_err(RemoteClientError::from)
94    }
95}