acta_maker_sdk/ws/managed/
outbound.rs1use crate::ws::client::PreparedClientMessage;
2use crate::ws::types::ClientMessage;
3use tokio::sync::oneshot;
4
5use super::ManagedWsError;
6
7#[must_use = "dropping a SendTicket cancels the send if it has not been written yet"]
12pub struct SendTicket {
13 pub(super) rx: oneshot::Receiver<Result<(), ManagedWsError>>,
14}
15
16impl SendTicket {
17 pub async fn wait(self) -> Result<(), ManagedWsError> {
18 match self.rx.await {
19 Ok(result) => result,
20 Err(_) => Err(ManagedWsError::Disconnected),
21 }
22 }
23}
24
25#[derive(Debug, thiserror::Error)]
26#[non_exhaustive]
27pub enum OutboundMessageError {
28 #[error("taker_buy_unsupported")]
29 TakerBuyUnsupported,
30 #[error("batch contains {actual} quotes, maximum is {limit}")]
31 BatchTooLarge { actual: usize, limit: usize },
32 #[error("serialized message is {actual} bytes, maximum is {limit}")]
33 MessageTooLarge { actual: usize, limit: usize },
34 #[error("message serialization failed: {0}")]
35 Serialization(#[from] serde_json::Error),
36}
37
38pub(super) fn prepare_outbound(
39 message: &ClientMessage,
40 max_batch_quotes: usize,
41 max_message_size: usize,
42) -> Result<PreparedClientMessage, OutboundMessageError> {
43 if has_unsupported_buy(message) {
44 return Err(OutboundMessageError::TakerBuyUnsupported);
45 }
46 if let ClientMessage::BatchQuotes(batch) = message
47 && batch.quotes.len() > max_batch_quotes
48 {
49 return Err(OutboundMessageError::BatchTooLarge {
50 actual: batch.quotes.len(),
51 limit: max_batch_quotes,
52 });
53 }
54 let prepared = PreparedClientMessage::new(message)?;
55 if prepared.len() > max_message_size {
56 return Err(OutboundMessageError::MessageTooLarge {
57 actual: prepared.len(),
58 limit: max_message_size,
59 });
60 }
61 Ok(prepared)
62}
63
64fn has_unsupported_buy(message: &ClientMessage) -> bool {
66 matches!(message, ClientMessage::RfqRequest(request) if request.side.is_taker_buy())
67}