jacquard_api/chat_bsky/convo/
send_message.rs1#[allow(unused_imports)]
9use alloc::collections::BTreeMap;
10
11use crate::chat_bsky::convo::MessageInput;
12use crate::chat_bsky::convo::MessageView;
13#[allow(unused_imports)]
14use core::marker::PhantomData;
15use jacquard_common::deps::smol_str::SmolStr;
16use jacquard_common::types::value::Data;
17use jacquard_common::{BosStr, CowStr, DefaultStr, FromStaticStr};
18use jacquard_derive::{IntoStatic, open_union};
19use serde::{Deserialize, Serialize};
20
21#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
22#[serde(
23 rename_all = "camelCase",
24 bound(deserialize = "S: Deserialize<'de> + BosStr")
25)]
26pub struct SendMessage<S: BosStr = DefaultStr> {
27 pub convo_id: S,
28 pub message: MessageInput<S>,
29 #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
30 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
31}
32
33#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
34#[serde(
35 rename_all = "camelCase",
36 bound(deserialize = "S: Deserialize<'de> + BosStr")
37)]
38pub struct SendMessageOutput<S: BosStr = DefaultStr> {
39 #[serde(flatten)]
40 pub value: MessageView<S>,
41 #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
42 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
43}
44
45#[derive(
46 Serialize, Deserialize, Debug, Clone, PartialEq, Eq, thiserror::Error, miette::Diagnostic,
47)]
48#[serde(tag = "error", content = "message")]
49pub enum SendMessageError {
50 #[serde(rename = "ConvoLocked")]
51 ConvoLocked(Option<SmolStr>),
52 #[serde(rename = "InvalidConvo")]
53 InvalidConvo(Option<SmolStr>),
54 #[serde(rename = "ReplyTargetNotFound")]
55 ReplyTargetNotFound(Option<SmolStr>),
56 #[serde(untagged)]
58 Other {
59 error: SmolStr,
60 message: Option<SmolStr>,
61 },
62}
63
64impl core::fmt::Display for SendMessageError {
65 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
66 match self {
67 Self::ConvoLocked(msg) => {
68 write!(f, "ConvoLocked")?;
69 if let Some(msg) = msg {
70 write!(f, ": {}", msg)?;
71 }
72 Ok(())
73 }
74 Self::InvalidConvo(msg) => {
75 write!(f, "InvalidConvo")?;
76 if let Some(msg) = msg {
77 write!(f, ": {}", msg)?;
78 }
79 Ok(())
80 }
81 Self::ReplyTargetNotFound(msg) => {
82 write!(f, "ReplyTargetNotFound")?;
83 if let Some(msg) = msg {
84 write!(f, ": {}", msg)?;
85 }
86 Ok(())
87 }
88 Self::Other { error, message } => {
89 write!(f, "{}", error)?;
90 if let Some(msg) = message {
91 write!(f, ": {}", msg)?;
92 }
93 Ok(())
94 }
95 }
96 }
97}
98
99pub struct SendMessageResponse;
103impl jacquard_common::xrpc::XrpcResp for SendMessageResponse {
104 const NSID: &'static str = "chat.bsky.convo.sendMessage";
105 const ENCODING: &'static str = "application/json";
106 type Output<S: BosStr> = SendMessageOutput<S>;
107 type Err = SendMessageError;
108}
109
110impl<S: BosStr> jacquard_common::xrpc::XrpcRequest for SendMessage<S> {
111 const NSID: &'static str = "chat.bsky.convo.sendMessage";
112 const METHOD: jacquard_common::xrpc::XrpcMethod =
113 jacquard_common::xrpc::XrpcMethod::Procedure("application/json");
114 type Response = SendMessageResponse;
115}
116
117pub struct SendMessageRequest;
121impl jacquard_common::xrpc::XrpcEndpoint for SendMessageRequest {
122 const PATH: &'static str = "/xrpc/chat.bsky.convo.sendMessage";
123 const METHOD: jacquard_common::xrpc::XrpcMethod =
124 jacquard_common::xrpc::XrpcMethod::Procedure("application/json");
125 type Request<S: BosStr> = SendMessage<S>;
126 type Response = SendMessageResponse;
127}
128
129pub mod send_message_state {
130
131 pub use crate::builder_types::{IsSet, IsUnset, Set, Unset};
132 #[allow(unused)]
133 use ::core::marker::PhantomData;
134 mod sealed {
135 pub trait Sealed {}
136 }
137 pub trait State: sealed::Sealed {
139 type ConvoId;
140 type Message;
141 }
142 pub struct Empty(());
144 impl sealed::Sealed for Empty {}
145 impl State for Empty {
146 type ConvoId = Unset;
147 type Message = Unset;
148 }
149 pub struct SetConvoId<St: State = Empty>(PhantomData<fn() -> St>);
151 impl<St: State> sealed::Sealed for SetConvoId<St> {}
152 impl<St: State> State for SetConvoId<St> {
153 type ConvoId = Set<members::convo_id>;
154 type Message = St::Message;
155 }
156 pub struct SetMessage<St: State = Empty>(PhantomData<fn() -> St>);
158 impl<St: State> sealed::Sealed for SetMessage<St> {}
159 impl<St: State> State for SetMessage<St> {
160 type ConvoId = St::ConvoId;
161 type Message = Set<members::message>;
162 }
163 #[allow(non_camel_case_types)]
165 pub mod members {
166 pub struct convo_id(());
168 pub struct message(());
170 }
171}
172
173pub struct SendMessageBuilder<St: send_message_state::State, S: BosStr = DefaultStr> {
175 _state: PhantomData<fn() -> St>,
176 _fields: (Option<S>, Option<MessageInput<S>>),
177 _type: PhantomData<fn() -> S>,
178}
179
180impl SendMessage<DefaultStr> {
181 pub fn new() -> SendMessageBuilder<send_message_state::Empty, DefaultStr> {
183 SendMessageBuilder::new()
184 }
185}
186
187impl<S: BosStr> SendMessage<S> {
188 pub fn builder() -> SendMessageBuilder<send_message_state::Empty, S> {
190 SendMessageBuilder::builder()
191 }
192}
193
194impl SendMessageBuilder<send_message_state::Empty, DefaultStr> {
195 pub fn new() -> Self {
197 SendMessageBuilder {
198 _state: PhantomData,
199 _fields: (None, None),
200 _type: PhantomData,
201 }
202 }
203}
204
205impl<S: BosStr> SendMessageBuilder<send_message_state::Empty, S> {
206 pub fn builder() -> Self {
208 SendMessageBuilder {
209 _state: PhantomData,
210 _fields: (None, None),
211 _type: PhantomData,
212 }
213 }
214}
215
216impl<St, S: BosStr> SendMessageBuilder<St, S>
217where
218 St: send_message_state::State,
219 St::ConvoId: send_message_state::IsUnset,
220{
221 pub fn convo_id(
223 mut self,
224 value: impl Into<S>,
225 ) -> SendMessageBuilder<send_message_state::SetConvoId<St>, S> {
226 self._fields.0 = Option::Some(value.into());
227 SendMessageBuilder {
228 _state: PhantomData,
229 _fields: self._fields,
230 _type: PhantomData,
231 }
232 }
233}
234
235impl<St, S: BosStr> SendMessageBuilder<St, S>
236where
237 St: send_message_state::State,
238 St::Message: send_message_state::IsUnset,
239{
240 pub fn message(
242 mut self,
243 value: impl Into<MessageInput<S>>,
244 ) -> SendMessageBuilder<send_message_state::SetMessage<St>, S> {
245 self._fields.1 = Option::Some(value.into());
246 SendMessageBuilder {
247 _state: PhantomData,
248 _fields: self._fields,
249 _type: PhantomData,
250 }
251 }
252}
253
254impl<St, S: BosStr> SendMessageBuilder<St, S>
255where
256 St: send_message_state::State,
257 St::ConvoId: send_message_state::IsSet,
258 St::Message: send_message_state::IsSet,
259{
260 pub fn build(self) -> SendMessage<S> {
262 SendMessage {
263 convo_id: self._fields.0.unwrap(),
264 message: self._fields.1.unwrap(),
265 extra_data: Default::default(),
266 }
267 }
268 pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> SendMessage<S> {
270 SendMessage {
271 convo_id: self._fields.0.unwrap(),
272 message: self._fields.1.unwrap(),
273 extra_data: Some(extra_data),
274 }
275 }
276}