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::ClientError;
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(&mut self) -> Result<mpsc::UnboundedReceiver<IncomingMessage>, ClientError>;
20
21    /// Request a rendezvous code from the proxy server
22    async fn request_rendezvous(&self) -> Result<(), ClientError>;
23
24    /// Request the identity associated with a rendezvous code
25    async fn request_identity(&self, code: RendezvousCode) -> Result<(), ClientError>;
26
27    /// Send a message to a peer by their fingerprint
28    async fn send_to(
29        &self,
30        fingerprint: IdentityFingerprint,
31        data: Vec<u8>,
32    ) -> Result<(), ClientError>;
33
34    /// Disconnect from the proxy server
35    async fn disconnect(&mut self) -> Result<(), ClientError>;
36}
37
38/// Default implementation using ProxyProtocolClient from ap-proxy
39#[cfg(feature = "native-websocket")]
40pub struct DefaultProxyClient {
41    inner: ProxyProtocolClient,
42}
43
44#[cfg(feature = "native-websocket")]
45impl DefaultProxyClient {
46    pub fn new(config: ProxyClientConfig) -> Self {
47        Self {
48            inner: ProxyProtocolClient::new(config),
49        }
50    }
51}
52
53#[cfg(feature = "native-websocket")]
54#[async_trait]
55impl ProxyClient for DefaultProxyClient {
56    async fn connect(&mut self) -> Result<mpsc::UnboundedReceiver<IncomingMessage>, ClientError> {
57        self.inner.connect().await.map_err(ClientError::from)
58    }
59
60    async fn request_rendezvous(&self) -> Result<(), ClientError> {
61        self.inner
62            .request_rendezvous()
63            .await
64            .map_err(ClientError::from)
65    }
66
67    async fn request_identity(&self, code: RendezvousCode) -> Result<(), ClientError> {
68        self.inner
69            .request_identity(code)
70            .await
71            .map_err(ClientError::from)
72    }
73
74    async fn send_to(
75        &self,
76        fingerprint: IdentityFingerprint,
77        data: Vec<u8>,
78    ) -> Result<(), ClientError> {
79        self.inner
80            .send_to(fingerprint, data)
81            .await
82            .map_err(ClientError::from)
83    }
84
85    async fn disconnect(&mut self) -> Result<(), ClientError> {
86        self.inner.disconnect().await.map_err(ClientError::from)
87    }
88}