1#[allow(unused_imports)]
9use alloc::collections::BTreeMap;
10
11#[allow(unused_imports)]
12use core::marker::PhantomData;
13use jacquard_common::CowStr;
14
15#[allow(unused_imports)]
16use jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation;
17use jacquard_common::types::collection::{Collection, RecordError};
18use jacquard_common::types::string::{AtUri, Cid, Datetime, Language};
19use jacquard_common::types::uri::{RecordUri, UriError};
20use jacquard_common::xrpc::XrpcResp;
21use jacquard_derive::{IntoStatic, lexicon, open_union};
22use jacquard_lexicon::lexicon::LexiconDoc;
23use jacquard_lexicon::schema::LexiconSchema;
24
25#[allow(unused_imports)]
26use jacquard_lexicon::validation::{ConstraintError, ValidationPath};
27use serde::{Serialize, Deserialize};
28use crate::app_bsky::embed::external::ExternalRecord;
29use crate::app_bsky::embed::images::Images;
30use crate::app_bsky::embed::record::Record;
31use crate::app_bsky::embed::record_with_media::RecordWithMedia;
32use crate::app_bsky::embed::video::Video;
33use crate::app_bsky::richtext::facet::Facet;
34use crate::com_atproto::label::SelfLabels;
35use crate::com_atproto::repo::strong_ref::StrongRef;
36use crate::app_bsky::feed::post;
37#[lexicon]
40#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
41#[serde(rename_all = "camelCase")]
42pub struct Entity<'a> {
43 #[serde(borrow)]
44 pub index: post::TextSlice<'a>,
45 #[serde(borrow)]
47 pub r#type: CowStr<'a>,
48 #[serde(borrow)]
49 pub value: CowStr<'a>,
50}
51
52#[lexicon]
55#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
56#[serde(rename_all = "camelCase", rename = "app.bsky.feed.post", tag = "$type")]
57pub struct Post<'a> {
58 pub created_at: Datetime,
60 #[serde(skip_serializing_if = "Option::is_none")]
61 #[serde(borrow)]
62 pub embed: Option<PostEmbed<'a>>,
63 #[serde(skip_serializing_if = "Option::is_none")]
65 #[serde(borrow)]
66 pub entities: Option<Vec<post::Entity<'a>>>,
67 #[serde(skip_serializing_if = "Option::is_none")]
69 #[serde(borrow)]
70 pub facets: Option<Vec<Facet<'a>>>,
71 #[serde(skip_serializing_if = "Option::is_none")]
73 #[serde(borrow)]
74 pub labels: Option<SelfLabels<'a>>,
75 #[serde(skip_serializing_if = "Option::is_none")]
77 pub langs: Option<Vec<Language>>,
78 #[serde(skip_serializing_if = "Option::is_none")]
79 #[serde(borrow)]
80 pub reply: Option<post::ReplyRef<'a>>,
81 #[serde(skip_serializing_if = "Option::is_none")]
83 #[serde(borrow)]
84 pub tags: Option<Vec<CowStr<'a>>>,
85 #[serde(borrow)]
87 pub text: CowStr<'a>,
88}
89
90
91#[open_union]
92#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
93#[serde(tag = "$type", bound(deserialize = "'de: 'a"))]
94pub enum PostEmbed<'a> {
95 #[serde(rename = "app.bsky.embed.images")]
96 Images(Box<Images<'a>>),
97 #[serde(rename = "app.bsky.embed.video")]
98 Video(Box<Video<'a>>),
99 #[serde(rename = "app.bsky.embed.external")]
100 External(Box<ExternalRecord<'a>>),
101 #[serde(rename = "app.bsky.embed.record")]
102 Record(Box<Record<'a>>),
103 #[serde(rename = "app.bsky.embed.recordWithMedia")]
104 RecordWithMedia(Box<RecordWithMedia<'a>>),
105}
106
107#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
110#[serde(rename_all = "camelCase")]
111pub struct PostGetRecordOutput<'a> {
112 #[serde(skip_serializing_if = "Option::is_none")]
113 #[serde(borrow)]
114 pub cid: Option<Cid<'a>>,
115 #[serde(borrow)]
116 pub uri: AtUri<'a>,
117 #[serde(borrow)]
118 pub value: Post<'a>,
119}
120
121
122#[lexicon]
123#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
124#[serde(rename_all = "camelCase")]
125pub struct ReplyRef<'a> {
126 #[serde(borrow)]
127 pub parent: StrongRef<'a>,
128 #[serde(borrow)]
129 pub root: StrongRef<'a>,
130}
131
132#[lexicon]
135#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
136#[serde(rename_all = "camelCase")]
137pub struct TextSlice<'a> {
138 pub end: i64,
139 pub start: i64,
140}
141
142impl<'a> Post<'a> {
143 pub fn uri(
144 uri: impl Into<CowStr<'a>>,
145 ) -> Result<RecordUri<'a, PostRecord>, UriError> {
146 RecordUri::try_from_uri(AtUri::new_cow(uri.into())?)
147 }
148}
149
150impl<'a> LexiconSchema for Entity<'a> {
151 fn nsid() -> &'static str {
152 "app.bsky.feed.post"
153 }
154 fn def_name() -> &'static str {
155 "entity"
156 }
157 fn lexicon_doc() -> LexiconDoc<'static> {
158 lexicon_doc_app_bsky_feed_post()
159 }
160 fn validate(&self) -> Result<(), ConstraintError> {
161 Ok(())
162 }
163}
164
165#[derive(Debug, Serialize, Deserialize)]
168pub struct PostRecord;
169impl XrpcResp for PostRecord {
170 const NSID: &'static str = "app.bsky.feed.post";
171 const ENCODING: &'static str = "application/json";
172 type Output<'de> = PostGetRecordOutput<'de>;
173 type Err<'de> = RecordError<'de>;
174}
175
176impl From<PostGetRecordOutput<'_>> for Post<'_> {
177 fn from(output: PostGetRecordOutput<'_>) -> Self {
178 use jacquard_common::IntoStatic;
179 output.value.into_static()
180 }
181}
182
183impl Collection for Post<'_> {
184 const NSID: &'static str = "app.bsky.feed.post";
185 type Record = PostRecord;
186}
187
188impl Collection for PostRecord {
189 const NSID: &'static str = "app.bsky.feed.post";
190 type Record = PostRecord;
191}
192
193impl<'a> LexiconSchema for Post<'a> {
194 fn nsid() -> &'static str {
195 "app.bsky.feed.post"
196 }
197 fn def_name() -> &'static str {
198 "main"
199 }
200 fn lexicon_doc() -> LexiconDoc<'static> {
201 lexicon_doc_app_bsky_feed_post()
202 }
203 fn validate(&self) -> Result<(), ConstraintError> {
204 if let Some(ref value) = self.langs {
205 #[allow(unused_comparisons)]
206 if value.len() > 3usize {
207 return Err(ConstraintError::MaxLength {
208 path: ValidationPath::from_field("langs"),
209 max: 3usize,
210 actual: value.len(),
211 });
212 }
213 }
214 if let Some(ref value) = self.tags {
215 #[allow(unused_comparisons)]
216 if value.len() > 8usize {
217 return Err(ConstraintError::MaxLength {
218 path: ValidationPath::from_field("tags"),
219 max: 8usize,
220 actual: value.len(),
221 });
222 }
223 }
224 {
225 let value = &self.text;
226 #[allow(unused_comparisons)]
227 if <str>::len(value.as_ref()) > 3000usize {
228 return Err(ConstraintError::MaxLength {
229 path: ValidationPath::from_field("text"),
230 max: 3000usize,
231 actual: <str>::len(value.as_ref()),
232 });
233 }
234 }
235 {
236 let value = &self.text;
237 {
238 let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
239 if count > 300usize {
240 return Err(ConstraintError::MaxGraphemes {
241 path: ValidationPath::from_field("text"),
242 max: 300usize,
243 actual: count,
244 });
245 }
246 }
247 }
248 Ok(())
249 }
250}
251
252impl<'a> LexiconSchema for ReplyRef<'a> {
253 fn nsid() -> &'static str {
254 "app.bsky.feed.post"
255 }
256 fn def_name() -> &'static str {
257 "replyRef"
258 }
259 fn lexicon_doc() -> LexiconDoc<'static> {
260 lexicon_doc_app_bsky_feed_post()
261 }
262 fn validate(&self) -> Result<(), ConstraintError> {
263 Ok(())
264 }
265}
266
267impl<'a> LexiconSchema for TextSlice<'a> {
268 fn nsid() -> &'static str {
269 "app.bsky.feed.post"
270 }
271 fn def_name() -> &'static str {
272 "textSlice"
273 }
274 fn lexicon_doc() -> LexiconDoc<'static> {
275 lexicon_doc_app_bsky_feed_post()
276 }
277 fn validate(&self) -> Result<(), ConstraintError> {
278 {
279 let value = &self.end;
280 if *value < 0i64 {
281 return Err(ConstraintError::Minimum {
282 path: ValidationPath::from_field("end"),
283 min: 0i64,
284 actual: *value,
285 });
286 }
287 }
288 {
289 let value = &self.start;
290 if *value < 0i64 {
291 return Err(ConstraintError::Minimum {
292 path: ValidationPath::from_field("start"),
293 min: 0i64,
294 actual: *value,
295 });
296 }
297 }
298 Ok(())
299 }
300}
301
302pub mod entity_state {
303
304 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
305 #[allow(unused)]
306 use ::core::marker::PhantomData;
307 mod sealed {
308 pub trait Sealed {}
309 }
310 pub trait State: sealed::Sealed {
312 type Value;
313 type Type;
314 type Index;
315 }
316 pub struct Empty(());
318 impl sealed::Sealed for Empty {}
319 impl State for Empty {
320 type Value = Unset;
321 type Type = Unset;
322 type Index = Unset;
323 }
324 pub struct SetValue<S: State = Empty>(PhantomData<fn() -> S>);
326 impl<S: State> sealed::Sealed for SetValue<S> {}
327 impl<S: State> State for SetValue<S> {
328 type Value = Set<members::value>;
329 type Type = S::Type;
330 type Index = S::Index;
331 }
332 pub struct SetType<S: State = Empty>(PhantomData<fn() -> S>);
334 impl<S: State> sealed::Sealed for SetType<S> {}
335 impl<S: State> State for SetType<S> {
336 type Value = S::Value;
337 type Type = Set<members::r#type>;
338 type Index = S::Index;
339 }
340 pub struct SetIndex<S: State = Empty>(PhantomData<fn() -> S>);
342 impl<S: State> sealed::Sealed for SetIndex<S> {}
343 impl<S: State> State for SetIndex<S> {
344 type Value = S::Value;
345 type Type = S::Type;
346 type Index = Set<members::index>;
347 }
348 #[allow(non_camel_case_types)]
350 pub mod members {
351 pub struct value(());
353 pub struct r#type(());
355 pub struct index(());
357 }
358}
359
360pub struct EntityBuilder<'a, S: entity_state::State> {
362 _state: PhantomData<fn() -> S>,
363 _fields: (Option<post::TextSlice<'a>>, Option<CowStr<'a>>, Option<CowStr<'a>>),
364 _lifetime: PhantomData<&'a ()>,
365}
366
367impl<'a> Entity<'a> {
368 pub fn new() -> EntityBuilder<'a, entity_state::Empty> {
370 EntityBuilder::new()
371 }
372}
373
374impl<'a> EntityBuilder<'a, entity_state::Empty> {
375 pub fn new() -> Self {
377 EntityBuilder {
378 _state: PhantomData,
379 _fields: (None, None, None),
380 _lifetime: PhantomData,
381 }
382 }
383}
384
385impl<'a, S> EntityBuilder<'a, S>
386where
387 S: entity_state::State,
388 S::Index: entity_state::IsUnset,
389{
390 pub fn index(
392 mut self,
393 value: impl Into<post::TextSlice<'a>>,
394 ) -> EntityBuilder<'a, entity_state::SetIndex<S>> {
395 self._fields.0 = Option::Some(value.into());
396 EntityBuilder {
397 _state: PhantomData,
398 _fields: self._fields,
399 _lifetime: PhantomData,
400 }
401 }
402}
403
404impl<'a, S> EntityBuilder<'a, S>
405where
406 S: entity_state::State,
407 S::Type: entity_state::IsUnset,
408{
409 pub fn r#type(
411 mut self,
412 value: impl Into<CowStr<'a>>,
413 ) -> EntityBuilder<'a, entity_state::SetType<S>> {
414 self._fields.1 = Option::Some(value.into());
415 EntityBuilder {
416 _state: PhantomData,
417 _fields: self._fields,
418 _lifetime: PhantomData,
419 }
420 }
421}
422
423impl<'a, S> EntityBuilder<'a, S>
424where
425 S: entity_state::State,
426 S::Value: entity_state::IsUnset,
427{
428 pub fn value(
430 mut self,
431 value: impl Into<CowStr<'a>>,
432 ) -> EntityBuilder<'a, entity_state::SetValue<S>> {
433 self._fields.2 = Option::Some(value.into());
434 EntityBuilder {
435 _state: PhantomData,
436 _fields: self._fields,
437 _lifetime: PhantomData,
438 }
439 }
440}
441
442impl<'a, S> EntityBuilder<'a, S>
443where
444 S: entity_state::State,
445 S::Value: entity_state::IsSet,
446 S::Type: entity_state::IsSet,
447 S::Index: entity_state::IsSet,
448{
449 pub fn build(self) -> Entity<'a> {
451 Entity {
452 index: self._fields.0.unwrap(),
453 r#type: self._fields.1.unwrap(),
454 value: self._fields.2.unwrap(),
455 extra_data: Default::default(),
456 }
457 }
458 pub fn build_with_data(
460 self,
461 extra_data: BTreeMap<
462 jacquard_common::deps::smol_str::SmolStr,
463 jacquard_common::types::value::Data<'a>,
464 >,
465 ) -> Entity<'a> {
466 Entity {
467 index: self._fields.0.unwrap(),
468 r#type: self._fields.1.unwrap(),
469 value: self._fields.2.unwrap(),
470 extra_data: Some(extra_data),
471 }
472 }
473}
474
475fn lexicon_doc_app_bsky_feed_post() -> LexiconDoc<'static> {
476 #[allow(unused_imports)]
477 use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
478 use jacquard_lexicon::lexicon::*;
479 use alloc::collections::BTreeMap;
480 LexiconDoc {
481 lexicon: Lexicon::Lexicon1,
482 id: CowStr::new_static("app.bsky.feed.post"),
483 defs: {
484 let mut map = BTreeMap::new();
485 map.insert(
486 SmolStr::new_static("entity"),
487 LexUserType::Object(LexObject {
488 description: Some(
489 CowStr::new_static("Deprecated: use facets instead."),
490 ),
491 required: Some(
492 vec![
493 SmolStr::new_static("index"), SmolStr::new_static("type"),
494 SmolStr::new_static("value")
495 ],
496 ),
497 properties: {
498 #[allow(unused_mut)]
499 let mut map = BTreeMap::new();
500 map.insert(
501 SmolStr::new_static("index"),
502 LexObjectProperty::Ref(LexRef {
503 r#ref: CowStr::new_static("#textSlice"),
504 ..Default::default()
505 }),
506 );
507 map.insert(
508 SmolStr::new_static("type"),
509 LexObjectProperty::String(LexString {
510 description: Some(
511 CowStr::new_static(
512 "Expected values are 'mention' and 'link'.",
513 ),
514 ),
515 ..Default::default()
516 }),
517 );
518 map.insert(
519 SmolStr::new_static("value"),
520 LexObjectProperty::String(LexString { ..Default::default() }),
521 );
522 map
523 },
524 ..Default::default()
525 }),
526 );
527 map.insert(
528 SmolStr::new_static("main"),
529 LexUserType::Record(LexRecord {
530 description: Some(
531 CowStr::new_static("Record containing a Bluesky post."),
532 ),
533 key: Some(CowStr::new_static("tid")),
534 record: LexRecordRecord::Object(LexObject {
535 required: Some(
536 vec![
537 SmolStr::new_static("text"),
538 SmolStr::new_static("createdAt")
539 ],
540 ),
541 properties: {
542 #[allow(unused_mut)]
543 let mut map = BTreeMap::new();
544 map.insert(
545 SmolStr::new_static("createdAt"),
546 LexObjectProperty::String(LexString {
547 description: Some(
548 CowStr::new_static(
549 "Client-declared timestamp when this post was originally created.",
550 ),
551 ),
552 format: Some(LexStringFormat::Datetime),
553 ..Default::default()
554 }),
555 );
556 map.insert(
557 SmolStr::new_static("embed"),
558 LexObjectProperty::Union(LexRefUnion {
559 refs: vec![
560 CowStr::new_static("app.bsky.embed.images"),
561 CowStr::new_static("app.bsky.embed.video"),
562 CowStr::new_static("app.bsky.embed.external"),
563 CowStr::new_static("app.bsky.embed.record"),
564 CowStr::new_static("app.bsky.embed.recordWithMedia")
565 ],
566 ..Default::default()
567 }),
568 );
569 map.insert(
570 SmolStr::new_static("entities"),
571 LexObjectProperty::Array(LexArray {
572 description: Some(
573 CowStr::new_static(
574 "DEPRECATED: replaced by app.bsky.richtext.facet.",
575 ),
576 ),
577 items: LexArrayItem::Ref(LexRef {
578 r#ref: CowStr::new_static("#entity"),
579 ..Default::default()
580 }),
581 ..Default::default()
582 }),
583 );
584 map.insert(
585 SmolStr::new_static("facets"),
586 LexObjectProperty::Array(LexArray {
587 description: Some(
588 CowStr::new_static(
589 "Annotations of text (mentions, URLs, hashtags, etc)",
590 ),
591 ),
592 items: LexArrayItem::Ref(LexRef {
593 r#ref: CowStr::new_static("app.bsky.richtext.facet"),
594 ..Default::default()
595 }),
596 ..Default::default()
597 }),
598 );
599 map.insert(
600 SmolStr::new_static("labels"),
601 LexObjectProperty::Union(LexRefUnion {
602 description: Some(
603 CowStr::new_static(
604 "Self-label values for this post. Effectively content warnings.",
605 ),
606 ),
607 refs: vec![
608 CowStr::new_static("com.atproto.label.defs#selfLabels")
609 ],
610 ..Default::default()
611 }),
612 );
613 map.insert(
614 SmolStr::new_static("langs"),
615 LexObjectProperty::Array(LexArray {
616 description: Some(
617 CowStr::new_static(
618 "Indicates human language of post primary text content.",
619 ),
620 ),
621 items: LexArrayItem::String(LexString {
622 format: Some(LexStringFormat::Language),
623 ..Default::default()
624 }),
625 max_length: Some(3usize),
626 ..Default::default()
627 }),
628 );
629 map.insert(
630 SmolStr::new_static("reply"),
631 LexObjectProperty::Ref(LexRef {
632 r#ref: CowStr::new_static("#replyRef"),
633 ..Default::default()
634 }),
635 );
636 map.insert(
637 SmolStr::new_static("tags"),
638 LexObjectProperty::Array(LexArray {
639 description: Some(
640 CowStr::new_static(
641 "Additional hashtags, in addition to any included in post text and facets.",
642 ),
643 ),
644 items: LexArrayItem::String(LexString {
645 max_length: Some(640usize),
646 max_graphemes: Some(64usize),
647 ..Default::default()
648 }),
649 max_length: Some(8usize),
650 ..Default::default()
651 }),
652 );
653 map.insert(
654 SmolStr::new_static("text"),
655 LexObjectProperty::String(LexString {
656 description: Some(
657 CowStr::new_static(
658 "The primary post content. May be an empty string, if there are embeds.",
659 ),
660 ),
661 max_length: Some(3000usize),
662 max_graphemes: Some(300usize),
663 ..Default::default()
664 }),
665 );
666 map
667 },
668 ..Default::default()
669 }),
670 ..Default::default()
671 }),
672 );
673 map.insert(
674 SmolStr::new_static("replyRef"),
675 LexUserType::Object(LexObject {
676 required: Some(
677 vec![SmolStr::new_static("root"), SmolStr::new_static("parent")],
678 ),
679 properties: {
680 #[allow(unused_mut)]
681 let mut map = BTreeMap::new();
682 map.insert(
683 SmolStr::new_static("parent"),
684 LexObjectProperty::Ref(LexRef {
685 r#ref: CowStr::new_static("com.atproto.repo.strongRef"),
686 ..Default::default()
687 }),
688 );
689 map.insert(
690 SmolStr::new_static("root"),
691 LexObjectProperty::Ref(LexRef {
692 r#ref: CowStr::new_static("com.atproto.repo.strongRef"),
693 ..Default::default()
694 }),
695 );
696 map
697 },
698 ..Default::default()
699 }),
700 );
701 map.insert(
702 SmolStr::new_static("textSlice"),
703 LexUserType::Object(LexObject {
704 description: Some(
705 CowStr::new_static(
706 "Deprecated. Use app.bsky.richtext instead -- A text segment. Start is inclusive, end is exclusive. Indices are for utf16-encoded strings.",
707 ),
708 ),
709 required: Some(
710 vec![SmolStr::new_static("start"), SmolStr::new_static("end")],
711 ),
712 properties: {
713 #[allow(unused_mut)]
714 let mut map = BTreeMap::new();
715 map.insert(
716 SmolStr::new_static("end"),
717 LexObjectProperty::Integer(LexInteger {
718 minimum: Some(0i64),
719 ..Default::default()
720 }),
721 );
722 map.insert(
723 SmolStr::new_static("start"),
724 LexObjectProperty::Integer(LexInteger {
725 minimum: Some(0i64),
726 ..Default::default()
727 }),
728 );
729 map
730 },
731 ..Default::default()
732 }),
733 );
734 map
735 },
736 ..Default::default()
737 }
738}
739
740pub mod post_state {
741
742 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
743 #[allow(unused)]
744 use ::core::marker::PhantomData;
745 mod sealed {
746 pub trait Sealed {}
747 }
748 pub trait State: sealed::Sealed {
750 type Text;
751 type CreatedAt;
752 }
753 pub struct Empty(());
755 impl sealed::Sealed for Empty {}
756 impl State for Empty {
757 type Text = Unset;
758 type CreatedAt = Unset;
759 }
760 pub struct SetText<S: State = Empty>(PhantomData<fn() -> S>);
762 impl<S: State> sealed::Sealed for SetText<S> {}
763 impl<S: State> State for SetText<S> {
764 type Text = Set<members::text>;
765 type CreatedAt = S::CreatedAt;
766 }
767 pub struct SetCreatedAt<S: State = Empty>(PhantomData<fn() -> S>);
769 impl<S: State> sealed::Sealed for SetCreatedAt<S> {}
770 impl<S: State> State for SetCreatedAt<S> {
771 type Text = S::Text;
772 type CreatedAt = Set<members::created_at>;
773 }
774 #[allow(non_camel_case_types)]
776 pub mod members {
777 pub struct text(());
779 pub struct created_at(());
781 }
782}
783
784pub struct PostBuilder<'a, S: post_state::State> {
786 _state: PhantomData<fn() -> S>,
787 _fields: (
788 Option<Datetime>,
789 Option<PostEmbed<'a>>,
790 Option<Vec<post::Entity<'a>>>,
791 Option<Vec<Facet<'a>>>,
792 Option<SelfLabels<'a>>,
793 Option<Vec<Language>>,
794 Option<post::ReplyRef<'a>>,
795 Option<Vec<CowStr<'a>>>,
796 Option<CowStr<'a>>,
797 ),
798 _lifetime: PhantomData<&'a ()>,
799}
800
801impl<'a> Post<'a> {
802 pub fn new() -> PostBuilder<'a, post_state::Empty> {
804 PostBuilder::new()
805 }
806}
807
808impl<'a> PostBuilder<'a, post_state::Empty> {
809 pub fn new() -> Self {
811 PostBuilder {
812 _state: PhantomData,
813 _fields: (None, None, None, None, None, None, None, None, None),
814 _lifetime: PhantomData,
815 }
816 }
817}
818
819impl<'a, S> PostBuilder<'a, S>
820where
821 S: post_state::State,
822 S::CreatedAt: post_state::IsUnset,
823{
824 pub fn created_at(
826 mut self,
827 value: impl Into<Datetime>,
828 ) -> PostBuilder<'a, post_state::SetCreatedAt<S>> {
829 self._fields.0 = Option::Some(value.into());
830 PostBuilder {
831 _state: PhantomData,
832 _fields: self._fields,
833 _lifetime: PhantomData,
834 }
835 }
836}
837
838impl<'a, S: post_state::State> PostBuilder<'a, S> {
839 pub fn embed(mut self, value: impl Into<Option<PostEmbed<'a>>>) -> Self {
841 self._fields.1 = value.into();
842 self
843 }
844 pub fn maybe_embed(mut self, value: Option<PostEmbed<'a>>) -> Self {
846 self._fields.1 = value;
847 self
848 }
849}
850
851impl<'a, S: post_state::State> PostBuilder<'a, S> {
852 pub fn entities(mut self, value: impl Into<Option<Vec<post::Entity<'a>>>>) -> Self {
854 self._fields.2 = value.into();
855 self
856 }
857 pub fn maybe_entities(mut self, value: Option<Vec<post::Entity<'a>>>) -> Self {
859 self._fields.2 = value;
860 self
861 }
862}
863
864impl<'a, S: post_state::State> PostBuilder<'a, S> {
865 pub fn facets(mut self, value: impl Into<Option<Vec<Facet<'a>>>>) -> Self {
867 self._fields.3 = value.into();
868 self
869 }
870 pub fn maybe_facets(mut self, value: Option<Vec<Facet<'a>>>) -> Self {
872 self._fields.3 = value;
873 self
874 }
875}
876
877impl<'a, S: post_state::State> PostBuilder<'a, S> {
878 pub fn labels(mut self, value: impl Into<Option<SelfLabels<'a>>>) -> Self {
880 self._fields.4 = value.into();
881 self
882 }
883 pub fn maybe_labels(mut self, value: Option<SelfLabels<'a>>) -> Self {
885 self._fields.4 = value;
886 self
887 }
888}
889
890impl<'a, S: post_state::State> PostBuilder<'a, S> {
891 pub fn langs(mut self, value: impl Into<Option<Vec<Language>>>) -> Self {
893 self._fields.5 = value.into();
894 self
895 }
896 pub fn maybe_langs(mut self, value: Option<Vec<Language>>) -> Self {
898 self._fields.5 = value;
899 self
900 }
901}
902
903impl<'a, S: post_state::State> PostBuilder<'a, S> {
904 pub fn reply(mut self, value: impl Into<Option<post::ReplyRef<'a>>>) -> Self {
906 self._fields.6 = value.into();
907 self
908 }
909 pub fn maybe_reply(mut self, value: Option<post::ReplyRef<'a>>) -> Self {
911 self._fields.6 = value;
912 self
913 }
914}
915
916impl<'a, S: post_state::State> PostBuilder<'a, S> {
917 pub fn tags(mut self, value: impl Into<Option<Vec<CowStr<'a>>>>) -> Self {
919 self._fields.7 = value.into();
920 self
921 }
922 pub fn maybe_tags(mut self, value: Option<Vec<CowStr<'a>>>) -> Self {
924 self._fields.7 = value;
925 self
926 }
927}
928
929impl<'a, S> PostBuilder<'a, S>
930where
931 S: post_state::State,
932 S::Text: post_state::IsUnset,
933{
934 pub fn text(
936 mut self,
937 value: impl Into<CowStr<'a>>,
938 ) -> PostBuilder<'a, post_state::SetText<S>> {
939 self._fields.8 = Option::Some(value.into());
940 PostBuilder {
941 _state: PhantomData,
942 _fields: self._fields,
943 _lifetime: PhantomData,
944 }
945 }
946}
947
948impl<'a, S> PostBuilder<'a, S>
949where
950 S: post_state::State,
951 S::Text: post_state::IsSet,
952 S::CreatedAt: post_state::IsSet,
953{
954 pub fn build(self) -> Post<'a> {
956 Post {
957 created_at: self._fields.0.unwrap(),
958 embed: self._fields.1,
959 entities: self._fields.2,
960 facets: self._fields.3,
961 labels: self._fields.4,
962 langs: self._fields.5,
963 reply: self._fields.6,
964 tags: self._fields.7,
965 text: self._fields.8.unwrap(),
966 extra_data: Default::default(),
967 }
968 }
969 pub fn build_with_data(
971 self,
972 extra_data: BTreeMap<
973 jacquard_common::deps::smol_str::SmolStr,
974 jacquard_common::types::value::Data<'a>,
975 >,
976 ) -> Post<'a> {
977 Post {
978 created_at: self._fields.0.unwrap(),
979 embed: self._fields.1,
980 entities: self._fields.2,
981 facets: self._fields.3,
982 labels: self._fields.4,
983 langs: self._fields.5,
984 reply: self._fields.6,
985 tags: self._fields.7,
986 text: self._fields.8.unwrap(),
987 extra_data: Some(extra_data),
988 }
989 }
990}
991
992pub mod reply_ref_state {
993
994 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
995 #[allow(unused)]
996 use ::core::marker::PhantomData;
997 mod sealed {
998 pub trait Sealed {}
999 }
1000 pub trait State: sealed::Sealed {
1002 type Parent;
1003 type Root;
1004 }
1005 pub struct Empty(());
1007 impl sealed::Sealed for Empty {}
1008 impl State for Empty {
1009 type Parent = Unset;
1010 type Root = Unset;
1011 }
1012 pub struct SetParent<S: State = Empty>(PhantomData<fn() -> S>);
1014 impl<S: State> sealed::Sealed for SetParent<S> {}
1015 impl<S: State> State for SetParent<S> {
1016 type Parent = Set<members::parent>;
1017 type Root = S::Root;
1018 }
1019 pub struct SetRoot<S: State = Empty>(PhantomData<fn() -> S>);
1021 impl<S: State> sealed::Sealed for SetRoot<S> {}
1022 impl<S: State> State for SetRoot<S> {
1023 type Parent = S::Parent;
1024 type Root = Set<members::root>;
1025 }
1026 #[allow(non_camel_case_types)]
1028 pub mod members {
1029 pub struct parent(());
1031 pub struct root(());
1033 }
1034}
1035
1036pub struct ReplyRefBuilder<'a, S: reply_ref_state::State> {
1038 _state: PhantomData<fn() -> S>,
1039 _fields: (Option<StrongRef<'a>>, Option<StrongRef<'a>>),
1040 _lifetime: PhantomData<&'a ()>,
1041}
1042
1043impl<'a> ReplyRef<'a> {
1044 pub fn new() -> ReplyRefBuilder<'a, reply_ref_state::Empty> {
1046 ReplyRefBuilder::new()
1047 }
1048}
1049
1050impl<'a> ReplyRefBuilder<'a, reply_ref_state::Empty> {
1051 pub fn new() -> Self {
1053 ReplyRefBuilder {
1054 _state: PhantomData,
1055 _fields: (None, None),
1056 _lifetime: PhantomData,
1057 }
1058 }
1059}
1060
1061impl<'a, S> ReplyRefBuilder<'a, S>
1062where
1063 S: reply_ref_state::State,
1064 S::Parent: reply_ref_state::IsUnset,
1065{
1066 pub fn parent(
1068 mut self,
1069 value: impl Into<StrongRef<'a>>,
1070 ) -> ReplyRefBuilder<'a, reply_ref_state::SetParent<S>> {
1071 self._fields.0 = Option::Some(value.into());
1072 ReplyRefBuilder {
1073 _state: PhantomData,
1074 _fields: self._fields,
1075 _lifetime: PhantomData,
1076 }
1077 }
1078}
1079
1080impl<'a, S> ReplyRefBuilder<'a, S>
1081where
1082 S: reply_ref_state::State,
1083 S::Root: reply_ref_state::IsUnset,
1084{
1085 pub fn root(
1087 mut self,
1088 value: impl Into<StrongRef<'a>>,
1089 ) -> ReplyRefBuilder<'a, reply_ref_state::SetRoot<S>> {
1090 self._fields.1 = Option::Some(value.into());
1091 ReplyRefBuilder {
1092 _state: PhantomData,
1093 _fields: self._fields,
1094 _lifetime: PhantomData,
1095 }
1096 }
1097}
1098
1099impl<'a, S> ReplyRefBuilder<'a, S>
1100where
1101 S: reply_ref_state::State,
1102 S::Parent: reply_ref_state::IsSet,
1103 S::Root: reply_ref_state::IsSet,
1104{
1105 pub fn build(self) -> ReplyRef<'a> {
1107 ReplyRef {
1108 parent: self._fields.0.unwrap(),
1109 root: self._fields.1.unwrap(),
1110 extra_data: Default::default(),
1111 }
1112 }
1113 pub fn build_with_data(
1115 self,
1116 extra_data: BTreeMap<
1117 jacquard_common::deps::smol_str::SmolStr,
1118 jacquard_common::types::value::Data<'a>,
1119 >,
1120 ) -> ReplyRef<'a> {
1121 ReplyRef {
1122 parent: self._fields.0.unwrap(),
1123 root: self._fields.1.unwrap(),
1124 extra_data: Some(extra_data),
1125 }
1126 }
1127}
1128
1129pub mod text_slice_state {
1130
1131 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
1132 #[allow(unused)]
1133 use ::core::marker::PhantomData;
1134 mod sealed {
1135 pub trait Sealed {}
1136 }
1137 pub trait State: sealed::Sealed {
1139 type Start;
1140 type End;
1141 }
1142 pub struct Empty(());
1144 impl sealed::Sealed for Empty {}
1145 impl State for Empty {
1146 type Start = Unset;
1147 type End = Unset;
1148 }
1149 pub struct SetStart<S: State = Empty>(PhantomData<fn() -> S>);
1151 impl<S: State> sealed::Sealed for SetStart<S> {}
1152 impl<S: State> State for SetStart<S> {
1153 type Start = Set<members::start>;
1154 type End = S::End;
1155 }
1156 pub struct SetEnd<S: State = Empty>(PhantomData<fn() -> S>);
1158 impl<S: State> sealed::Sealed for SetEnd<S> {}
1159 impl<S: State> State for SetEnd<S> {
1160 type Start = S::Start;
1161 type End = Set<members::end>;
1162 }
1163 #[allow(non_camel_case_types)]
1165 pub mod members {
1166 pub struct start(());
1168 pub struct end(());
1170 }
1171}
1172
1173pub struct TextSliceBuilder<'a, S: text_slice_state::State> {
1175 _state: PhantomData<fn() -> S>,
1176 _fields: (Option<i64>, Option<i64>),
1177 _lifetime: PhantomData<&'a ()>,
1178}
1179
1180impl<'a> TextSlice<'a> {
1181 pub fn new() -> TextSliceBuilder<'a, text_slice_state::Empty> {
1183 TextSliceBuilder::new()
1184 }
1185}
1186
1187impl<'a> TextSliceBuilder<'a, text_slice_state::Empty> {
1188 pub fn new() -> Self {
1190 TextSliceBuilder {
1191 _state: PhantomData,
1192 _fields: (None, None),
1193 _lifetime: PhantomData,
1194 }
1195 }
1196}
1197
1198impl<'a, S> TextSliceBuilder<'a, S>
1199where
1200 S: text_slice_state::State,
1201 S::End: text_slice_state::IsUnset,
1202{
1203 pub fn end(
1205 mut self,
1206 value: impl Into<i64>,
1207 ) -> TextSliceBuilder<'a, text_slice_state::SetEnd<S>> {
1208 self._fields.0 = Option::Some(value.into());
1209 TextSliceBuilder {
1210 _state: PhantomData,
1211 _fields: self._fields,
1212 _lifetime: PhantomData,
1213 }
1214 }
1215}
1216
1217impl<'a, S> TextSliceBuilder<'a, S>
1218where
1219 S: text_slice_state::State,
1220 S::Start: text_slice_state::IsUnset,
1221{
1222 pub fn start(
1224 mut self,
1225 value: impl Into<i64>,
1226 ) -> TextSliceBuilder<'a, text_slice_state::SetStart<S>> {
1227 self._fields.1 = Option::Some(value.into());
1228 TextSliceBuilder {
1229 _state: PhantomData,
1230 _fields: self._fields,
1231 _lifetime: PhantomData,
1232 }
1233 }
1234}
1235
1236impl<'a, S> TextSliceBuilder<'a, S>
1237where
1238 S: text_slice_state::State,
1239 S::Start: text_slice_state::IsSet,
1240 S::End: text_slice_state::IsSet,
1241{
1242 pub fn build(self) -> TextSlice<'a> {
1244 TextSlice {
1245 end: self._fields.0.unwrap(),
1246 start: self._fields.1.unwrap(),
1247 extra_data: Default::default(),
1248 }
1249 }
1250 pub fn build_with_data(
1252 self,
1253 extra_data: BTreeMap<
1254 jacquard_common::deps::smol_str::SmolStr,
1255 jacquard_common::types::value::Data<'a>,
1256 >,
1257 ) -> TextSlice<'a> {
1258 TextSlice {
1259 end: self._fields.0.unwrap(),
1260 start: self._fields.1.unwrap(),
1261 extra_data: Some(extra_data),
1262 }
1263 }
1264}