1use crate::error::ApiError;
2use crate::message::{Action, FromMessage, IntoMessage, Message};
3use crate::request::Request;
4
5use lafere::client::Connection;
6pub use lafere::client::{Config, ReconStrat};
7use lafere::error::TaskError;
8pub use lafere::packet::PlainBytes;
9use lafere::packet::{Packet, PacketBytes};
10use lafere::util::ByteStream;
11
12#[cfg(feature = "encrypted")]
13use crypto::signature::PublicKey;
14#[cfg(feature = "encrypted")]
15pub use lafere::packet::EncryptedBytes;
16
17pub struct Client<A, B> {
18 inner: Connection<Message<A, B>>,
19}
20
21impl<A> Client<A, PlainBytes>
22where
23 A: Action + Send + 'static,
24{
25 pub fn new<S>(
27 stream: S,
28 cfg: Config,
29 recon_strat: Option<ReconStrat<S>>,
30 ) -> Self
31 where
32 S: ByteStream,
33 {
34 Self {
35 inner: Connection::new(stream, cfg, recon_strat),
36 }
37 }
38}
39
40#[cfg(feature = "encrypted")]
41#[cfg_attr(docsrs, doc(cfg(feature = "encrypted")))]
42impl<A> Client<A, EncryptedBytes>
43where
44 A: Action + Send + 'static,
45{
46 pub fn new_encrypted<S>(
47 stream: S,
48 cfg: Config,
49 recon_strat: Option<ReconStrat<S>>,
50 pub_key: PublicKey,
51 ) -> Self
52 where
53 S: ByteStream,
54 {
55 Self {
56 inner: Connection::new_encrypted(stream, cfg, recon_strat, pub_key),
57 }
58 }
59}
60
61impl<A, B> Client<A, B>
62where
63 A: Action,
64 B: PacketBytes,
65{
66 pub async fn request<R>(&self, req: R) -> Result<R::Response, R::Error>
67 where
68 R: Request<Action = A>,
69 R: IntoMessage<A, B>,
70 R::Response: FromMessage<A, B>,
71 R::Error: FromMessage<A, B>,
72 {
73 let mut msg =
74 req.into_message().map_err(R::Error::from_message_error)?;
75 msg.header_mut().set_action(R::ACTION);
76
77 let res = self
78 .inner
79 .request(msg)
80 .await
81 .map_err(R::Error::from_request_error)?;
82
83 if res.is_success() {
85 R::Response::from_message(res).map_err(R::Error::from_message_error)
86 } else {
87 R::Error::from_message(res)
88 .map(Err)
89 .map_err(R::Error::from_message_error)?
90 }
91 }
92}
93
94impl<A, B> Client<A, B> {
95 pub async fn close(self) -> Result<(), TaskError> {
96 self.inner.close().await
97 }
98}