1#[allow(unused_imports)]
9use alloc::collections::BTreeMap;
10
11use crate::app_bsky::feed::PostView;
12#[allow(unused_imports)]
13use core::marker::PhantomData;
14use jacquard_common::deps::smol_str::SmolStr;
15use jacquard_common::types::ident::AtIdentifier;
16use jacquard_common::types::string::{AtUri, Language, UriValue};
17use jacquard_common::types::value::Data;
18use jacquard_common::{BosStr, CowStr, DefaultStr, FromStaticStr};
19use jacquard_derive::{IntoStatic, open_union};
20use serde::{Deserialize, Serialize};
21
22#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
23#[serde(
24 rename_all = "camelCase",
25 bound(deserialize = "S: Deserialize<'de> + BosStr")
26)]
27pub struct SearchPostsV2<S: BosStr = DefaultStr> {
28 #[serde(skip_serializing_if = "Option::is_none")]
29 pub all_time: Option<bool>,
30 #[serde(skip_serializing_if = "Option::is_none")]
31 pub authors: Option<Vec<AtIdentifier<S>>>,
32 #[serde(skip_serializing_if = "Option::is_none")]
33 pub cursor: Option<S>,
34 #[serde(skip_serializing_if = "Option::is_none")]
35 pub domains: Option<Vec<S>>,
36 #[serde(skip_serializing_if = "Option::is_none")]
37 pub embedded_at_uris: Option<Vec<AtUri<S>>>,
38 #[serde(skip_serializing_if = "Option::is_none")]
39 pub exclude_authors: Option<Vec<AtIdentifier<S>>>,
40 #[serde(skip_serializing_if = "Option::is_none")]
41 pub exclude_domains: Option<Vec<S>>,
42 #[serde(skip_serializing_if = "Option::is_none")]
43 pub exclude_embedded_at_uris: Option<Vec<AtUri<S>>>,
44 #[serde(skip_serializing_if = "Option::is_none")]
45 pub exclude_hashtags: Option<Vec<S>>,
46 #[serde(skip_serializing_if = "Option::is_none")]
47 pub exclude_languages: Option<Vec<Language>>,
48 #[serde(skip_serializing_if = "Option::is_none")]
49 pub exclude_mentions: Option<Vec<AtIdentifier<S>>>,
50 #[serde(skip_serializing_if = "Option::is_none")]
51 pub exclude_replies: Option<bool>,
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub exclude_urls: Option<Vec<UriValue<S>>>,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub following: Option<bool>,
56 #[serde(skip_serializing_if = "Option::is_none")]
57 pub has_media: Option<bool>,
58 #[serde(skip_serializing_if = "Option::is_none")]
59 pub has_video: Option<bool>,
60 #[serde(skip_serializing_if = "Option::is_none")]
61 pub hashtags: Option<Vec<S>>,
62 #[serde(skip_serializing_if = "Option::is_none")]
63 pub languages: Option<Vec<Language>>,
64 #[serde(default = "_default_limit")]
66 #[serde(skip_serializing_if = "Option::is_none")]
67 pub limit: Option<i64>,
68 #[serde(skip_serializing_if = "Option::is_none")]
69 pub mentions: Option<Vec<AtIdentifier<S>>>,
70 #[serde(skip_serializing_if = "Option::is_none")]
71 pub query: Option<S>,
72 #[serde(skip_serializing_if = "Option::is_none")]
73 pub query_language: Option<S>,
74 #[serde(skip_serializing_if = "Option::is_none")]
75 pub replies_only: Option<bool>,
76 #[serde(skip_serializing_if = "Option::is_none")]
77 pub reply_parent_uri: Option<AtUri<S>>,
78 #[serde(skip_serializing_if = "Option::is_none")]
79 pub since: Option<S>,
80 #[serde(skip_serializing_if = "Option::is_none")]
81 pub sort: Option<S>,
82 #[serde(skip_serializing_if = "Option::is_none")]
83 pub thread_root_uri: Option<AtUri<S>>,
84 #[serde(skip_serializing_if = "Option::is_none")]
85 pub until: Option<S>,
86 #[serde(skip_serializing_if = "Option::is_none")]
87 pub urls: Option<Vec<UriValue<S>>>,
88}
89
90#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
91#[serde(
92 rename_all = "camelCase",
93 bound(deserialize = "S: Deserialize<'de> + BosStr")
94)]
95pub struct SearchPostsV2Output<S: BosStr = DefaultStr> {
96 #[serde(skip_serializing_if = "Option::is_none")]
98 pub cursor: Option<S>,
99 #[serde(skip_serializing_if = "Option::is_none")]
101 pub detected_query_languages: Option<Vec<S>>,
102 #[serde(skip_serializing_if = "Option::is_none")]
104 pub hits_total: Option<i64>,
105 pub posts: Vec<PostView<S>>,
107 #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
108 pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
109}
110
111#[derive(
112 Serialize, Deserialize, Debug, Clone, PartialEq, Eq, thiserror::Error, miette::Diagnostic,
113)]
114#[serde(tag = "error", content = "message")]
115pub enum SearchPostsV2Error {
116 #[serde(rename = "BadQueryString")]
117 BadQueryString(Option<SmolStr>),
118 #[serde(untagged)]
120 Other {
121 error: SmolStr,
122 message: Option<SmolStr>,
123 },
124}
125
126impl core::fmt::Display for SearchPostsV2Error {
127 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
128 match self {
129 Self::BadQueryString(msg) => {
130 write!(f, "BadQueryString")?;
131 if let Some(msg) = msg {
132 write!(f, ": {}", msg)?;
133 }
134 Ok(())
135 }
136 Self::Other { error, message } => {
137 write!(f, "{}", error)?;
138 if let Some(msg) = message {
139 write!(f, ": {}", msg)?;
140 }
141 Ok(())
142 }
143 }
144 }
145}
146
147pub struct SearchPostsV2Response;
151impl jacquard_common::xrpc::XrpcResp for SearchPostsV2Response {
152 const NSID: &'static str = "app.bsky.feed.searchPostsV2";
153 const ENCODING: &'static str = "application/json";
154 type Output<S: BosStr> = SearchPostsV2Output<S>;
155 type Err = SearchPostsV2Error;
156}
157
158impl<S: BosStr> jacquard_common::xrpc::XrpcRequest for SearchPostsV2<S> {
159 const NSID: &'static str = "app.bsky.feed.searchPostsV2";
160 const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Query;
161 type Response = SearchPostsV2Response;
162}
163
164pub struct SearchPostsV2Request;
168impl jacquard_common::xrpc::XrpcEndpoint for SearchPostsV2Request {
169 const PATH: &'static str = "/xrpc/app.bsky.feed.searchPostsV2";
170 const METHOD: jacquard_common::xrpc::XrpcMethod = jacquard_common::xrpc::XrpcMethod::Query;
171 type Request<S: BosStr> = SearchPostsV2<S>;
172 type Response = SearchPostsV2Response;
173}
174
175fn _default_limit() -> Option<i64> {
176 Some(25i64)
177}
178
179pub mod search_posts_v2_state {
180
181 pub use crate::builder_types::{IsSet, IsUnset, Set, Unset};
182 #[allow(unused)]
183 use ::core::marker::PhantomData;
184 mod sealed {
185 pub trait Sealed {}
186 }
187 pub trait State: sealed::Sealed {}
189 pub struct Empty(());
191 impl sealed::Sealed for Empty {}
192 impl State for Empty {}
193 #[allow(non_camel_case_types)]
195 pub mod members {}
196}
197
198pub struct SearchPostsV2Builder<St: search_posts_v2_state::State, S: BosStr = DefaultStr> {
200 _state: PhantomData<fn() -> St>,
201 _fields: (
202 Option<bool>,
203 Option<Vec<AtIdentifier<S>>>,
204 Option<S>,
205 Option<Vec<S>>,
206 Option<Vec<AtUri<S>>>,
207 Option<Vec<AtIdentifier<S>>>,
208 Option<Vec<S>>,
209 Option<Vec<AtUri<S>>>,
210 Option<Vec<S>>,
211 Option<Vec<Language>>,
212 Option<Vec<AtIdentifier<S>>>,
213 Option<bool>,
214 Option<Vec<UriValue<S>>>,
215 Option<bool>,
216 Option<bool>,
217 Option<bool>,
218 Option<Vec<S>>,
219 Option<Vec<Language>>,
220 Option<i64>,
221 Option<Vec<AtIdentifier<S>>>,
222 Option<S>,
223 Option<S>,
224 Option<bool>,
225 Option<AtUri<S>>,
226 Option<S>,
227 Option<S>,
228 Option<AtUri<S>>,
229 Option<S>,
230 Option<Vec<UriValue<S>>>,
231 ),
232 _type: PhantomData<fn() -> S>,
233}
234
235impl SearchPostsV2<DefaultStr> {
236 pub fn new() -> SearchPostsV2Builder<search_posts_v2_state::Empty, DefaultStr> {
238 SearchPostsV2Builder::new()
239 }
240}
241
242impl<S: BosStr> SearchPostsV2<S> {
243 pub fn builder() -> SearchPostsV2Builder<search_posts_v2_state::Empty, S> {
245 SearchPostsV2Builder::builder()
246 }
247}
248
249impl SearchPostsV2Builder<search_posts_v2_state::Empty, DefaultStr> {
250 pub fn new() -> Self {
252 SearchPostsV2Builder {
253 _state: PhantomData,
254 _fields: (
255 None, None, None, None, None, None, None, None, None, None, None, None, None, None,
256 None, None, None, None, None, None, None, None, None, None, None, None, None, None,
257 None,
258 ),
259 _type: PhantomData,
260 }
261 }
262}
263
264impl<S: BosStr> SearchPostsV2Builder<search_posts_v2_state::Empty, S> {
265 pub fn builder() -> Self {
267 SearchPostsV2Builder {
268 _state: PhantomData,
269 _fields: (
270 None, None, None, None, None, None, None, None, None, None, None, None, None, None,
271 None, None, None, None, None, None, None, None, None, None, None, None, None, None,
272 None,
273 ),
274 _type: PhantomData,
275 }
276 }
277}
278
279impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
280 pub fn all_time(mut self, value: impl Into<Option<bool>>) -> Self {
282 self._fields.0 = value.into();
283 self
284 }
285 pub fn maybe_all_time(mut self, value: Option<bool>) -> Self {
287 self._fields.0 = value;
288 self
289 }
290}
291
292impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
293 pub fn authors(mut self, value: impl Into<Option<Vec<AtIdentifier<S>>>>) -> Self {
295 self._fields.1 = value.into();
296 self
297 }
298 pub fn maybe_authors(mut self, value: Option<Vec<AtIdentifier<S>>>) -> Self {
300 self._fields.1 = value;
301 self
302 }
303}
304
305impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
306 pub fn cursor(mut self, value: impl Into<Option<S>>) -> Self {
308 self._fields.2 = value.into();
309 self
310 }
311 pub fn maybe_cursor(mut self, value: Option<S>) -> Self {
313 self._fields.2 = value;
314 self
315 }
316}
317
318impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
319 pub fn domains(mut self, value: impl Into<Option<Vec<S>>>) -> Self {
321 self._fields.3 = value.into();
322 self
323 }
324 pub fn maybe_domains(mut self, value: Option<Vec<S>>) -> Self {
326 self._fields.3 = value;
327 self
328 }
329}
330
331impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
332 pub fn embedded_at_uris(mut self, value: impl Into<Option<Vec<AtUri<S>>>>) -> Self {
334 self._fields.4 = value.into();
335 self
336 }
337 pub fn maybe_embedded_at_uris(mut self, value: Option<Vec<AtUri<S>>>) -> Self {
339 self._fields.4 = value;
340 self
341 }
342}
343
344impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
345 pub fn exclude_authors(mut self, value: impl Into<Option<Vec<AtIdentifier<S>>>>) -> Self {
347 self._fields.5 = value.into();
348 self
349 }
350 pub fn maybe_exclude_authors(mut self, value: Option<Vec<AtIdentifier<S>>>) -> Self {
352 self._fields.5 = value;
353 self
354 }
355}
356
357impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
358 pub fn exclude_domains(mut self, value: impl Into<Option<Vec<S>>>) -> Self {
360 self._fields.6 = value.into();
361 self
362 }
363 pub fn maybe_exclude_domains(mut self, value: Option<Vec<S>>) -> Self {
365 self._fields.6 = value;
366 self
367 }
368}
369
370impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
371 pub fn exclude_embedded_at_uris(mut self, value: impl Into<Option<Vec<AtUri<S>>>>) -> Self {
373 self._fields.7 = value.into();
374 self
375 }
376 pub fn maybe_exclude_embedded_at_uris(mut self, value: Option<Vec<AtUri<S>>>) -> Self {
378 self._fields.7 = value;
379 self
380 }
381}
382
383impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
384 pub fn exclude_hashtags(mut self, value: impl Into<Option<Vec<S>>>) -> Self {
386 self._fields.8 = value.into();
387 self
388 }
389 pub fn maybe_exclude_hashtags(mut self, value: Option<Vec<S>>) -> Self {
391 self._fields.8 = value;
392 self
393 }
394}
395
396impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
397 pub fn exclude_languages(mut self, value: impl Into<Option<Vec<Language>>>) -> Self {
399 self._fields.9 = value.into();
400 self
401 }
402 pub fn maybe_exclude_languages(mut self, value: Option<Vec<Language>>) -> Self {
404 self._fields.9 = value;
405 self
406 }
407}
408
409impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
410 pub fn exclude_mentions(mut self, value: impl Into<Option<Vec<AtIdentifier<S>>>>) -> Self {
412 self._fields.10 = value.into();
413 self
414 }
415 pub fn maybe_exclude_mentions(mut self, value: Option<Vec<AtIdentifier<S>>>) -> Self {
417 self._fields.10 = value;
418 self
419 }
420}
421
422impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
423 pub fn exclude_replies(mut self, value: impl Into<Option<bool>>) -> Self {
425 self._fields.11 = value.into();
426 self
427 }
428 pub fn maybe_exclude_replies(mut self, value: Option<bool>) -> Self {
430 self._fields.11 = value;
431 self
432 }
433}
434
435impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
436 pub fn exclude_urls(mut self, value: impl Into<Option<Vec<UriValue<S>>>>) -> Self {
438 self._fields.12 = value.into();
439 self
440 }
441 pub fn maybe_exclude_urls(mut self, value: Option<Vec<UriValue<S>>>) -> Self {
443 self._fields.12 = value;
444 self
445 }
446}
447
448impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
449 pub fn following(mut self, value: impl Into<Option<bool>>) -> Self {
451 self._fields.13 = value.into();
452 self
453 }
454 pub fn maybe_following(mut self, value: Option<bool>) -> Self {
456 self._fields.13 = value;
457 self
458 }
459}
460
461impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
462 pub fn has_media(mut self, value: impl Into<Option<bool>>) -> Self {
464 self._fields.14 = value.into();
465 self
466 }
467 pub fn maybe_has_media(mut self, value: Option<bool>) -> Self {
469 self._fields.14 = value;
470 self
471 }
472}
473
474impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
475 pub fn has_video(mut self, value: impl Into<Option<bool>>) -> Self {
477 self._fields.15 = value.into();
478 self
479 }
480 pub fn maybe_has_video(mut self, value: Option<bool>) -> Self {
482 self._fields.15 = value;
483 self
484 }
485}
486
487impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
488 pub fn hashtags(mut self, value: impl Into<Option<Vec<S>>>) -> Self {
490 self._fields.16 = value.into();
491 self
492 }
493 pub fn maybe_hashtags(mut self, value: Option<Vec<S>>) -> Self {
495 self._fields.16 = value;
496 self
497 }
498}
499
500impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
501 pub fn languages(mut self, value: impl Into<Option<Vec<Language>>>) -> Self {
503 self._fields.17 = value.into();
504 self
505 }
506 pub fn maybe_languages(mut self, value: Option<Vec<Language>>) -> Self {
508 self._fields.17 = value;
509 self
510 }
511}
512
513impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
514 pub fn limit(mut self, value: impl Into<Option<i64>>) -> Self {
516 self._fields.18 = value.into();
517 self
518 }
519 pub fn maybe_limit(mut self, value: Option<i64>) -> Self {
521 self._fields.18 = value;
522 self
523 }
524}
525
526impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
527 pub fn mentions(mut self, value: impl Into<Option<Vec<AtIdentifier<S>>>>) -> Self {
529 self._fields.19 = value.into();
530 self
531 }
532 pub fn maybe_mentions(mut self, value: Option<Vec<AtIdentifier<S>>>) -> Self {
534 self._fields.19 = value;
535 self
536 }
537}
538
539impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
540 pub fn query(mut self, value: impl Into<Option<S>>) -> Self {
542 self._fields.20 = value.into();
543 self
544 }
545 pub fn maybe_query(mut self, value: Option<S>) -> Self {
547 self._fields.20 = value;
548 self
549 }
550}
551
552impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
553 pub fn query_language(mut self, value: impl Into<Option<S>>) -> Self {
555 self._fields.21 = value.into();
556 self
557 }
558 pub fn maybe_query_language(mut self, value: Option<S>) -> Self {
560 self._fields.21 = value;
561 self
562 }
563}
564
565impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
566 pub fn replies_only(mut self, value: impl Into<Option<bool>>) -> Self {
568 self._fields.22 = value.into();
569 self
570 }
571 pub fn maybe_replies_only(mut self, value: Option<bool>) -> Self {
573 self._fields.22 = value;
574 self
575 }
576}
577
578impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
579 pub fn reply_parent_uri(mut self, value: impl Into<Option<AtUri<S>>>) -> Self {
581 self._fields.23 = value.into();
582 self
583 }
584 pub fn maybe_reply_parent_uri(mut self, value: Option<AtUri<S>>) -> Self {
586 self._fields.23 = value;
587 self
588 }
589}
590
591impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
592 pub fn since(mut self, value: impl Into<Option<S>>) -> Self {
594 self._fields.24 = value.into();
595 self
596 }
597 pub fn maybe_since(mut self, value: Option<S>) -> Self {
599 self._fields.24 = value;
600 self
601 }
602}
603
604impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
605 pub fn sort(mut self, value: impl Into<Option<S>>) -> Self {
607 self._fields.25 = value.into();
608 self
609 }
610 pub fn maybe_sort(mut self, value: Option<S>) -> Self {
612 self._fields.25 = value;
613 self
614 }
615}
616
617impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
618 pub fn thread_root_uri(mut self, value: impl Into<Option<AtUri<S>>>) -> Self {
620 self._fields.26 = value.into();
621 self
622 }
623 pub fn maybe_thread_root_uri(mut self, value: Option<AtUri<S>>) -> Self {
625 self._fields.26 = value;
626 self
627 }
628}
629
630impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
631 pub fn until(mut self, value: impl Into<Option<S>>) -> Self {
633 self._fields.27 = value.into();
634 self
635 }
636 pub fn maybe_until(mut self, value: Option<S>) -> Self {
638 self._fields.27 = value;
639 self
640 }
641}
642
643impl<St: search_posts_v2_state::State, S: BosStr> SearchPostsV2Builder<St, S> {
644 pub fn urls(mut self, value: impl Into<Option<Vec<UriValue<S>>>>) -> Self {
646 self._fields.28 = value.into();
647 self
648 }
649 pub fn maybe_urls(mut self, value: Option<Vec<UriValue<S>>>) -> Self {
651 self._fields.28 = value;
652 self
653 }
654}
655
656impl<St, S: BosStr> SearchPostsV2Builder<St, S>
657where
658 St: search_posts_v2_state::State,
659{
660 pub fn build(self) -> SearchPostsV2<S> {
662 SearchPostsV2 {
663 all_time: self._fields.0,
664 authors: self._fields.1,
665 cursor: self._fields.2,
666 domains: self._fields.3,
667 embedded_at_uris: self._fields.4,
668 exclude_authors: self._fields.5,
669 exclude_domains: self._fields.6,
670 exclude_embedded_at_uris: self._fields.7,
671 exclude_hashtags: self._fields.8,
672 exclude_languages: self._fields.9,
673 exclude_mentions: self._fields.10,
674 exclude_replies: self._fields.11,
675 exclude_urls: self._fields.12,
676 following: self._fields.13,
677 has_media: self._fields.14,
678 has_video: self._fields.15,
679 hashtags: self._fields.16,
680 languages: self._fields.17,
681 limit: self._fields.18,
682 mentions: self._fields.19,
683 query: self._fields.20,
684 query_language: self._fields.21,
685 replies_only: self._fields.22,
686 reply_parent_uri: self._fields.23,
687 since: self._fields.24,
688 sort: self._fields.25,
689 thread_root_uri: self._fields.26,
690 until: self._fields.27,
691 urls: self._fields.28,
692 }
693 }
694}