lafere_api/
client.rs

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	// plain
26	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		// now deserialize the response
84		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}