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