jacquard_api/app_bsky/feed/
search_posts.rs1#[allow(unused_imports)]
9use alloc::collections::BTreeMap;
10
11#[allow(unused_imports)]
12use core::marker::PhantomData;
13use jacquard_common::CowStr;
14use jacquard_common::types::ident::AtIdentifier;
15use jacquard_common::types::string::{Language, UriValue};
16use jacquard_derive::{IntoStatic, lexicon, open_union};
17use serde::{Serialize, Deserialize};
18use crate::app_bsky::feed::PostView;
19
20#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
21#[serde(rename_all = "camelCase")]
22pub struct SearchPosts<'a> {
23 #[serde(skip_serializing_if = "Option::is_none")]
24 #[serde(borrow)]
25 pub author: Option<AtIdentifier<'a>>,
26 #[serde(skip_serializing_if = "Option::is_none")]
27 #[serde(borrow)]
28 pub cursor: Option<CowStr<'a>>,
29 #[serde(skip_serializing_if = "Option::is_none")]
30 #[serde(borrow)]
31 pub domain: Option<CowStr<'a>>,
32 #[serde(skip_serializing_if = "Option::is_none")]
33 pub lang: Option<Language>,
34 #[serde(default = "_default_limit")]
36 #[serde(skip_serializing_if = "Option::is_none")]
37 pub limit: Option<i64>,
38 #[serde(skip_serializing_if = "Option::is_none")]
39 #[serde(borrow)]
40 pub mentions: Option<AtIdentifier<'a>>,
41 #[serde(borrow)]
42 pub q: CowStr<'a>,
43 #[serde(skip_serializing_if = "Option::is_none")]
44 #[serde(borrow)]
45 pub since: Option<CowStr<'a>>,
46 #[serde(default = "_default_sort")]
48 #[serde(skip_serializing_if = "Option::is_none")]
49 #[serde(borrow)]
50 pub sort: Option<CowStr<'a>>,
51 #[serde(skip_serializing_if = "Option::is_none")]
52 #[serde(borrow)]
53 pub tag: Option<Vec<CowStr<'a>>>,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 #[serde(borrow)]
56 pub until: Option<CowStr<'a>>,
57 #[serde(skip_serializing_if = "Option::is_none")]
58 #[serde(borrow)]
59 pub url: Option<UriValue<'a>>,
60}
61
62
63#[lexicon]
64#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
65#[serde(rename_all = "camelCase")]
66pub struct SearchPostsOutput<'a> {
67 #[serde(skip_serializing_if = "Option::is_none")]
68 #[serde(borrow)]
69 pub cursor: Option<CowStr<'a>>,
70 #[serde(skip_serializing_if = "Option::is_none")]
72 pub hits_total: Option<i64>,
73 #[serde(borrow)]
74 pub posts: Vec<PostView<'a>>,
75}
76
77
78#[open_union]
79#[derive(
80 Serialize,
81 Deserialize,
82 Debug,
83 Clone,
84 PartialEq,
85 Eq,
86 thiserror::Error,
87 miette::Diagnostic,
88 IntoStatic
89)]
90
91#[serde(tag = "error", content = "message")]
92#[serde(bound(deserialize = "'de: 'a"))]
93pub enum SearchPostsError<'a> {
94 #[serde(rename = "BadQueryString")]
95 BadQueryString(Option<CowStr<'a>>),
96}
97
98impl core::fmt::Display for SearchPostsError<'_> {
99 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
100 match self {
101 Self::BadQueryString(msg) => {
102 write!(f, "BadQueryString")?;
103 if let Some(msg) = msg {
104 write!(f, ": {}", msg)?;
105 }
106 Ok(())
107 }
108 Self::Unknown(err) => write!(f, "Unknown error: {:?}", err),
109 }
110 }
111}
112
113pub struct SearchPostsResponse;
115impl jacquard_common::xrpc::XrpcResp for SearchPostsResponse {
116 const NSID: &'static str = "app.bsky.feed.searchPosts";
117 const ENCODING: &'static str = "application/json";
118 type Output<'de> = SearchPostsOutput<'de>;
119 type Err<'de> = SearchPostsError<'de>;
120}
121
122impl<'a> jacquard_common::xrpc::XrpcRequest for SearchPosts<'a> {
123 const NSID: &'static str = "app.bsky.feed.searchPosts";
124 const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Query;
125 type Response = SearchPostsResponse;
126}
127
128pub struct SearchPostsRequest;
130impl jacquard_common::xrpc::XrpcEndpoint for SearchPostsRequest {
131 const PATH: &'static str = "/xrpc/app.bsky.feed.searchPosts";
132 const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Query;
133 type Request<'de> = SearchPosts<'de>;
134 type Response = SearchPostsResponse;
135}
136
137fn _default_limit() -> Option<i64> {
138 Some(25i64)
139}
140
141fn _default_sort() -> Option<CowStr<'static>> {
142 Some(CowStr::from("latest"))
143}
144
145pub mod search_posts_state {
146
147 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
148 #[allow(unused)]
149 use ::core::marker::PhantomData;
150 mod sealed {
151 pub trait Sealed {}
152 }
153 pub trait State: sealed::Sealed {
155 type Q;
156 }
157 pub struct Empty(());
159 impl sealed::Sealed for Empty {}
160 impl State for Empty {
161 type Q = Unset;
162 }
163 pub struct SetQ<S: State = Empty>(PhantomData<fn() -> S>);
165 impl<S: State> sealed::Sealed for SetQ<S> {}
166 impl<S: State> State for SetQ<S> {
167 type Q = Set<members::q>;
168 }
169 #[allow(non_camel_case_types)]
171 pub mod members {
172 pub struct q(());
174 }
175}
176
177pub struct SearchPostsBuilder<'a, S: search_posts_state::State> {
179 _state: PhantomData<fn() -> S>,
180 _fields: (
181 Option<AtIdentifier<'a>>,
182 Option<CowStr<'a>>,
183 Option<CowStr<'a>>,
184 Option<Language>,
185 Option<i64>,
186 Option<AtIdentifier<'a>>,
187 Option<CowStr<'a>>,
188 Option<CowStr<'a>>,
189 Option<CowStr<'a>>,
190 Option<Vec<CowStr<'a>>>,
191 Option<CowStr<'a>>,
192 Option<UriValue<'a>>,
193 ),
194 _lifetime: PhantomData<&'a ()>,
195}
196
197impl<'a> SearchPosts<'a> {
198 pub fn new() -> SearchPostsBuilder<'a, search_posts_state::Empty> {
200 SearchPostsBuilder::new()
201 }
202}
203
204impl<'a> SearchPostsBuilder<'a, search_posts_state::Empty> {
205 pub fn new() -> Self {
207 SearchPostsBuilder {
208 _state: PhantomData,
209 _fields: (
210 None,
211 None,
212 None,
213 None,
214 None,
215 None,
216 None,
217 None,
218 None,
219 None,
220 None,
221 None,
222 ),
223 _lifetime: PhantomData,
224 }
225 }
226}
227
228impl<'a, S: search_posts_state::State> SearchPostsBuilder<'a, S> {
229 pub fn author(mut self, value: impl Into<Option<AtIdentifier<'a>>>) -> Self {
231 self._fields.0 = value.into();
232 self
233 }
234 pub fn maybe_author(mut self, value: Option<AtIdentifier<'a>>) -> Self {
236 self._fields.0 = value;
237 self
238 }
239}
240
241impl<'a, S: search_posts_state::State> SearchPostsBuilder<'a, S> {
242 pub fn cursor(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
244 self._fields.1 = value.into();
245 self
246 }
247 pub fn maybe_cursor(mut self, value: Option<CowStr<'a>>) -> Self {
249 self._fields.1 = value;
250 self
251 }
252}
253
254impl<'a, S: search_posts_state::State> SearchPostsBuilder<'a, S> {
255 pub fn domain(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
257 self._fields.2 = value.into();
258 self
259 }
260 pub fn maybe_domain(mut self, value: Option<CowStr<'a>>) -> Self {
262 self._fields.2 = value;
263 self
264 }
265}
266
267impl<'a, S: search_posts_state::State> SearchPostsBuilder<'a, S> {
268 pub fn lang(mut self, value: impl Into<Option<Language>>) -> Self {
270 self._fields.3 = value.into();
271 self
272 }
273 pub fn maybe_lang(mut self, value: Option<Language>) -> Self {
275 self._fields.3 = value;
276 self
277 }
278}
279
280impl<'a, S: search_posts_state::State> SearchPostsBuilder<'a, S> {
281 pub fn limit(mut self, value: impl Into<Option<i64>>) -> Self {
283 self._fields.4 = value.into();
284 self
285 }
286 pub fn maybe_limit(mut self, value: Option<i64>) -> Self {
288 self._fields.4 = value;
289 self
290 }
291}
292
293impl<'a, S: search_posts_state::State> SearchPostsBuilder<'a, S> {
294 pub fn mentions(mut self, value: impl Into<Option<AtIdentifier<'a>>>) -> Self {
296 self._fields.5 = value.into();
297 self
298 }
299 pub fn maybe_mentions(mut self, value: Option<AtIdentifier<'a>>) -> Self {
301 self._fields.5 = value;
302 self
303 }
304}
305
306impl<'a, S> SearchPostsBuilder<'a, S>
307where
308 S: search_posts_state::State,
309 S::Q: search_posts_state::IsUnset,
310{
311 pub fn q(
313 mut self,
314 value: impl Into<CowStr<'a>>,
315 ) -> SearchPostsBuilder<'a, search_posts_state::SetQ<S>> {
316 self._fields.6 = Option::Some(value.into());
317 SearchPostsBuilder {
318 _state: PhantomData,
319 _fields: self._fields,
320 _lifetime: PhantomData,
321 }
322 }
323}
324
325impl<'a, S: search_posts_state::State> SearchPostsBuilder<'a, S> {
326 pub fn since(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
328 self._fields.7 = value.into();
329 self
330 }
331 pub fn maybe_since(mut self, value: Option<CowStr<'a>>) -> Self {
333 self._fields.7 = value;
334 self
335 }
336}
337
338impl<'a, S: search_posts_state::State> SearchPostsBuilder<'a, S> {
339 pub fn sort(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
341 self._fields.8 = value.into();
342 self
343 }
344 pub fn maybe_sort(mut self, value: Option<CowStr<'a>>) -> Self {
346 self._fields.8 = value;
347 self
348 }
349}
350
351impl<'a, S: search_posts_state::State> SearchPostsBuilder<'a, S> {
352 pub fn tag(mut self, value: impl Into<Option<Vec<CowStr<'a>>>>) -> Self {
354 self._fields.9 = value.into();
355 self
356 }
357 pub fn maybe_tag(mut self, value: Option<Vec<CowStr<'a>>>) -> Self {
359 self._fields.9 = value;
360 self
361 }
362}
363
364impl<'a, S: search_posts_state::State> SearchPostsBuilder<'a, S> {
365 pub fn until(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
367 self._fields.10 = value.into();
368 self
369 }
370 pub fn maybe_until(mut self, value: Option<CowStr<'a>>) -> Self {
372 self._fields.10 = value;
373 self
374 }
375}
376
377impl<'a, S: search_posts_state::State> SearchPostsBuilder<'a, S> {
378 pub fn url(mut self, value: impl Into<Option<UriValue<'a>>>) -> Self {
380 self._fields.11 = value.into();
381 self
382 }
383 pub fn maybe_url(mut self, value: Option<UriValue<'a>>) -> Self {
385 self._fields.11 = value;
386 self
387 }
388}
389
390impl<'a, S> SearchPostsBuilder<'a, S>
391where
392 S: search_posts_state::State,
393 S::Q: search_posts_state::IsSet,
394{
395 pub fn build(self) -> SearchPosts<'a> {
397 SearchPosts {
398 author: self._fields.0,
399 cursor: self._fields.1,
400 domain: self._fields.2,
401 lang: self._fields.3,
402 limit: self._fields.4,
403 mentions: self._fields.5,
404 q: self._fields.6.unwrap(),
405 since: self._fields.7,
406 sort: self._fields.8,
407 tag: self._fields.9,
408 until: self._fields.10,
409 url: self._fields.11,
410 }
411 }
412}