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::string::{Did, UriValue};
18use jacquard_derive::{IntoStatic, lexicon, open_union};
19use jacquard_lexicon::lexicon::LexiconDoc;
20use jacquard_lexicon::schema::LexiconSchema;
21
22#[allow(unused_imports)]
23use jacquard_lexicon::validation::{ConstraintError, ValidationPath};
24use serde::{Serialize, Deserialize};
25use crate::app_bsky::richtext::facet;
26#[lexicon]
29#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
30#[serde(rename_all = "camelCase")]
31pub struct ByteSlice<'a> {
32 pub byte_end: i64,
33 pub byte_start: i64,
34}
35
36#[lexicon]
39#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
40#[serde(rename_all = "camelCase")]
41pub struct Link<'a> {
42 #[serde(borrow)]
43 pub uri: UriValue<'a>,
44}
45
46#[lexicon]
49#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
50#[serde(rename_all = "camelCase")]
51pub struct Facet<'a> {
52 #[serde(borrow)]
53 pub features: Vec<FacetFeaturesItem<'a>>,
54 #[serde(borrow)]
55 pub index: facet::ByteSlice<'a>,
56}
57
58
59#[open_union]
60#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
61#[serde(tag = "$type", bound(deserialize = "'de: 'a"))]
62pub enum FacetFeaturesItem<'a> {
63 #[serde(rename = "app.bsky.richtext.facet#mention")]
64 Mention(Box<facet::Mention<'a>>),
65 #[serde(rename = "app.bsky.richtext.facet#link")]
66 Link(Box<facet::Link<'a>>),
67 #[serde(rename = "app.bsky.richtext.facet#tag")]
68 Tag(Box<facet::Tag<'a>>),
69}
70
71#[lexicon]
74#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
75#[serde(rename_all = "camelCase")]
76pub struct Mention<'a> {
77 #[serde(borrow)]
78 pub did: Did<'a>,
79}
80
81#[lexicon]
84#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
85#[serde(rename_all = "camelCase")]
86pub struct Tag<'a> {
87 #[serde(borrow)]
88 pub tag: CowStr<'a>,
89}
90
91impl<'a> LexiconSchema for ByteSlice<'a> {
92 fn nsid() -> &'static str {
93 "app.bsky.richtext.facet"
94 }
95 fn def_name() -> &'static str {
96 "byteSlice"
97 }
98 fn lexicon_doc() -> LexiconDoc<'static> {
99 lexicon_doc_app_bsky_richtext_facet()
100 }
101 fn validate(&self) -> Result<(), ConstraintError> {
102 {
103 let value = &self.byte_end;
104 if *value < 0i64 {
105 return Err(ConstraintError::Minimum {
106 path: ValidationPath::from_field("byte_end"),
107 min: 0i64,
108 actual: *value,
109 });
110 }
111 }
112 {
113 let value = &self.byte_start;
114 if *value < 0i64 {
115 return Err(ConstraintError::Minimum {
116 path: ValidationPath::from_field("byte_start"),
117 min: 0i64,
118 actual: *value,
119 });
120 }
121 }
122 Ok(())
123 }
124}
125
126impl<'a> LexiconSchema for Link<'a> {
127 fn nsid() -> &'static str {
128 "app.bsky.richtext.facet"
129 }
130 fn def_name() -> &'static str {
131 "link"
132 }
133 fn lexicon_doc() -> LexiconDoc<'static> {
134 lexicon_doc_app_bsky_richtext_facet()
135 }
136 fn validate(&self) -> Result<(), ConstraintError> {
137 Ok(())
138 }
139}
140
141impl<'a> LexiconSchema for Facet<'a> {
142 fn nsid() -> &'static str {
143 "app.bsky.richtext.facet"
144 }
145 fn def_name() -> &'static str {
146 "main"
147 }
148 fn lexicon_doc() -> LexiconDoc<'static> {
149 lexicon_doc_app_bsky_richtext_facet()
150 }
151 fn validate(&self) -> Result<(), ConstraintError> {
152 Ok(())
153 }
154}
155
156impl<'a> LexiconSchema for Mention<'a> {
157 fn nsid() -> &'static str {
158 "app.bsky.richtext.facet"
159 }
160 fn def_name() -> &'static str {
161 "mention"
162 }
163 fn lexicon_doc() -> LexiconDoc<'static> {
164 lexicon_doc_app_bsky_richtext_facet()
165 }
166 fn validate(&self) -> Result<(), ConstraintError> {
167 Ok(())
168 }
169}
170
171impl<'a> LexiconSchema for Tag<'a> {
172 fn nsid() -> &'static str {
173 "app.bsky.richtext.facet"
174 }
175 fn def_name() -> &'static str {
176 "tag"
177 }
178 fn lexicon_doc() -> LexiconDoc<'static> {
179 lexicon_doc_app_bsky_richtext_facet()
180 }
181 fn validate(&self) -> Result<(), ConstraintError> {
182 {
183 let value = &self.tag;
184 #[allow(unused_comparisons)]
185 if <str>::len(value.as_ref()) > 640usize {
186 return Err(ConstraintError::MaxLength {
187 path: ValidationPath::from_field("tag"),
188 max: 640usize,
189 actual: <str>::len(value.as_ref()),
190 });
191 }
192 }
193 {
194 let value = &self.tag;
195 {
196 let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
197 if count > 64usize {
198 return Err(ConstraintError::MaxGraphemes {
199 path: ValidationPath::from_field("tag"),
200 max: 64usize,
201 actual: count,
202 });
203 }
204 }
205 }
206 Ok(())
207 }
208}
209
210pub mod byte_slice_state {
211
212 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
213 #[allow(unused)]
214 use ::core::marker::PhantomData;
215 mod sealed {
216 pub trait Sealed {}
217 }
218 pub trait State: sealed::Sealed {
220 type ByteStart;
221 type ByteEnd;
222 }
223 pub struct Empty(());
225 impl sealed::Sealed for Empty {}
226 impl State for Empty {
227 type ByteStart = Unset;
228 type ByteEnd = Unset;
229 }
230 pub struct SetByteStart<S: State = Empty>(PhantomData<fn() -> S>);
232 impl<S: State> sealed::Sealed for SetByteStart<S> {}
233 impl<S: State> State for SetByteStart<S> {
234 type ByteStart = Set<members::byte_start>;
235 type ByteEnd = S::ByteEnd;
236 }
237 pub struct SetByteEnd<S: State = Empty>(PhantomData<fn() -> S>);
239 impl<S: State> sealed::Sealed for SetByteEnd<S> {}
240 impl<S: State> State for SetByteEnd<S> {
241 type ByteStart = S::ByteStart;
242 type ByteEnd = Set<members::byte_end>;
243 }
244 #[allow(non_camel_case_types)]
246 pub mod members {
247 pub struct byte_start(());
249 pub struct byte_end(());
251 }
252}
253
254pub struct ByteSliceBuilder<'a, S: byte_slice_state::State> {
256 _state: PhantomData<fn() -> S>,
257 _fields: (Option<i64>, Option<i64>),
258 _lifetime: PhantomData<&'a ()>,
259}
260
261impl<'a> ByteSlice<'a> {
262 pub fn new() -> ByteSliceBuilder<'a, byte_slice_state::Empty> {
264 ByteSliceBuilder::new()
265 }
266}
267
268impl<'a> ByteSliceBuilder<'a, byte_slice_state::Empty> {
269 pub fn new() -> Self {
271 ByteSliceBuilder {
272 _state: PhantomData,
273 _fields: (None, None),
274 _lifetime: PhantomData,
275 }
276 }
277}
278
279impl<'a, S> ByteSliceBuilder<'a, S>
280where
281 S: byte_slice_state::State,
282 S::ByteEnd: byte_slice_state::IsUnset,
283{
284 pub fn byte_end(
286 mut self,
287 value: impl Into<i64>,
288 ) -> ByteSliceBuilder<'a, byte_slice_state::SetByteEnd<S>> {
289 self._fields.0 = Option::Some(value.into());
290 ByteSliceBuilder {
291 _state: PhantomData,
292 _fields: self._fields,
293 _lifetime: PhantomData,
294 }
295 }
296}
297
298impl<'a, S> ByteSliceBuilder<'a, S>
299where
300 S: byte_slice_state::State,
301 S::ByteStart: byte_slice_state::IsUnset,
302{
303 pub fn byte_start(
305 mut self,
306 value: impl Into<i64>,
307 ) -> ByteSliceBuilder<'a, byte_slice_state::SetByteStart<S>> {
308 self._fields.1 = Option::Some(value.into());
309 ByteSliceBuilder {
310 _state: PhantomData,
311 _fields: self._fields,
312 _lifetime: PhantomData,
313 }
314 }
315}
316
317impl<'a, S> ByteSliceBuilder<'a, S>
318where
319 S: byte_slice_state::State,
320 S::ByteStart: byte_slice_state::IsSet,
321 S::ByteEnd: byte_slice_state::IsSet,
322{
323 pub fn build(self) -> ByteSlice<'a> {
325 ByteSlice {
326 byte_end: self._fields.0.unwrap(),
327 byte_start: self._fields.1.unwrap(),
328 extra_data: Default::default(),
329 }
330 }
331 pub fn build_with_data(
333 self,
334 extra_data: BTreeMap<
335 jacquard_common::deps::smol_str::SmolStr,
336 jacquard_common::types::value::Data<'a>,
337 >,
338 ) -> ByteSlice<'a> {
339 ByteSlice {
340 byte_end: self._fields.0.unwrap(),
341 byte_start: self._fields.1.unwrap(),
342 extra_data: Some(extra_data),
343 }
344 }
345}
346
347fn lexicon_doc_app_bsky_richtext_facet() -> LexiconDoc<'static> {
348 #[allow(unused_imports)]
349 use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
350 use jacquard_lexicon::lexicon::*;
351 use alloc::collections::BTreeMap;
352 LexiconDoc {
353 lexicon: Lexicon::Lexicon1,
354 id: CowStr::new_static("app.bsky.richtext.facet"),
355 defs: {
356 let mut map = BTreeMap::new();
357 map.insert(
358 SmolStr::new_static("byteSlice"),
359 LexUserType::Object(LexObject {
360 description: Some(
361 CowStr::new_static(
362 "Specifies the sub-string range a facet feature applies to. Start index is inclusive, end index is exclusive. Indices are zero-indexed, counting bytes of the UTF-8 encoded text. NOTE: some languages, like Javascript, use UTF-16 or Unicode codepoints for string slice indexing; in these languages, convert to byte arrays before working with facets.",
363 ),
364 ),
365 required: Some(
366 vec![
367 SmolStr::new_static("byteStart"),
368 SmolStr::new_static("byteEnd")
369 ],
370 ),
371 properties: {
372 #[allow(unused_mut)]
373 let mut map = BTreeMap::new();
374 map.insert(
375 SmolStr::new_static("byteEnd"),
376 LexObjectProperty::Integer(LexInteger {
377 minimum: Some(0i64),
378 ..Default::default()
379 }),
380 );
381 map.insert(
382 SmolStr::new_static("byteStart"),
383 LexObjectProperty::Integer(LexInteger {
384 minimum: Some(0i64),
385 ..Default::default()
386 }),
387 );
388 map
389 },
390 ..Default::default()
391 }),
392 );
393 map.insert(
394 SmolStr::new_static("link"),
395 LexUserType::Object(LexObject {
396 description: Some(
397 CowStr::new_static(
398 "Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL.",
399 ),
400 ),
401 required: Some(vec![SmolStr::new_static("uri")]),
402 properties: {
403 #[allow(unused_mut)]
404 let mut map = BTreeMap::new();
405 map.insert(
406 SmolStr::new_static("uri"),
407 LexObjectProperty::String(LexString {
408 format: Some(LexStringFormat::Uri),
409 ..Default::default()
410 }),
411 );
412 map
413 },
414 ..Default::default()
415 }),
416 );
417 map.insert(
418 SmolStr::new_static("main"),
419 LexUserType::Object(LexObject {
420 description: Some(
421 CowStr::new_static(
422 "Annotation of a sub-string within rich text.",
423 ),
424 ),
425 required: Some(
426 vec![
427 SmolStr::new_static("index"), SmolStr::new_static("features")
428 ],
429 ),
430 properties: {
431 #[allow(unused_mut)]
432 let mut map = BTreeMap::new();
433 map.insert(
434 SmolStr::new_static("features"),
435 LexObjectProperty::Array(LexArray {
436 items: LexArrayItem::Union(LexRefUnion {
437 refs: vec![
438 CowStr::new_static("#mention"), CowStr::new_static("#link"),
439 CowStr::new_static("#tag")
440 ],
441 ..Default::default()
442 }),
443 ..Default::default()
444 }),
445 );
446 map.insert(
447 SmolStr::new_static("index"),
448 LexObjectProperty::Ref(LexRef {
449 r#ref: CowStr::new_static("#byteSlice"),
450 ..Default::default()
451 }),
452 );
453 map
454 },
455 ..Default::default()
456 }),
457 );
458 map.insert(
459 SmolStr::new_static("mention"),
460 LexUserType::Object(LexObject {
461 description: Some(
462 CowStr::new_static(
463 "Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID.",
464 ),
465 ),
466 required: Some(vec![SmolStr::new_static("did")]),
467 properties: {
468 #[allow(unused_mut)]
469 let mut map = BTreeMap::new();
470 map.insert(
471 SmolStr::new_static("did"),
472 LexObjectProperty::String(LexString {
473 format: Some(LexStringFormat::Did),
474 ..Default::default()
475 }),
476 );
477 map
478 },
479 ..Default::default()
480 }),
481 );
482 map.insert(
483 SmolStr::new_static("tag"),
484 LexUserType::Object(LexObject {
485 description: Some(
486 CowStr::new_static(
487 "Facet feature for a hashtag. The text usually includes a '#' prefix, but the facet reference should not (except in the case of 'double hash tags').",
488 ),
489 ),
490 required: Some(vec![SmolStr::new_static("tag")]),
491 properties: {
492 #[allow(unused_mut)]
493 let mut map = BTreeMap::new();
494 map.insert(
495 SmolStr::new_static("tag"),
496 LexObjectProperty::String(LexString {
497 max_length: Some(640usize),
498 max_graphemes: Some(64usize),
499 ..Default::default()
500 }),
501 );
502 map
503 },
504 ..Default::default()
505 }),
506 );
507 map
508 },
509 ..Default::default()
510 }
511}
512
513pub mod link_state {
514
515 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
516 #[allow(unused)]
517 use ::core::marker::PhantomData;
518 mod sealed {
519 pub trait Sealed {}
520 }
521 pub trait State: sealed::Sealed {
523 type Uri;
524 }
525 pub struct Empty(());
527 impl sealed::Sealed for Empty {}
528 impl State for Empty {
529 type Uri = Unset;
530 }
531 pub struct SetUri<S: State = Empty>(PhantomData<fn() -> S>);
533 impl<S: State> sealed::Sealed for SetUri<S> {}
534 impl<S: State> State for SetUri<S> {
535 type Uri = Set<members::uri>;
536 }
537 #[allow(non_camel_case_types)]
539 pub mod members {
540 pub struct uri(());
542 }
543}
544
545pub struct LinkBuilder<'a, S: link_state::State> {
547 _state: PhantomData<fn() -> S>,
548 _fields: (Option<UriValue<'a>>,),
549 _lifetime: PhantomData<&'a ()>,
550}
551
552impl<'a> Link<'a> {
553 pub fn new() -> LinkBuilder<'a, link_state::Empty> {
555 LinkBuilder::new()
556 }
557}
558
559impl<'a> LinkBuilder<'a, link_state::Empty> {
560 pub fn new() -> Self {
562 LinkBuilder {
563 _state: PhantomData,
564 _fields: (None,),
565 _lifetime: PhantomData,
566 }
567 }
568}
569
570impl<'a, S> LinkBuilder<'a, S>
571where
572 S: link_state::State,
573 S::Uri: link_state::IsUnset,
574{
575 pub fn uri(
577 mut self,
578 value: impl Into<UriValue<'a>>,
579 ) -> LinkBuilder<'a, link_state::SetUri<S>> {
580 self._fields.0 = Option::Some(value.into());
581 LinkBuilder {
582 _state: PhantomData,
583 _fields: self._fields,
584 _lifetime: PhantomData,
585 }
586 }
587}
588
589impl<'a, S> LinkBuilder<'a, S>
590where
591 S: link_state::State,
592 S::Uri: link_state::IsSet,
593{
594 pub fn build(self) -> Link<'a> {
596 Link {
597 uri: self._fields.0.unwrap(),
598 extra_data: Default::default(),
599 }
600 }
601 pub fn build_with_data(
603 self,
604 extra_data: BTreeMap<
605 jacquard_common::deps::smol_str::SmolStr,
606 jacquard_common::types::value::Data<'a>,
607 >,
608 ) -> Link<'a> {
609 Link {
610 uri: self._fields.0.unwrap(),
611 extra_data: Some(extra_data),
612 }
613 }
614}
615
616pub mod facet_state {
617
618 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
619 #[allow(unused)]
620 use ::core::marker::PhantomData;
621 mod sealed {
622 pub trait Sealed {}
623 }
624 pub trait State: sealed::Sealed {
626 type Index;
627 type Features;
628 }
629 pub struct Empty(());
631 impl sealed::Sealed for Empty {}
632 impl State for Empty {
633 type Index = Unset;
634 type Features = Unset;
635 }
636 pub struct SetIndex<S: State = Empty>(PhantomData<fn() -> S>);
638 impl<S: State> sealed::Sealed for SetIndex<S> {}
639 impl<S: State> State for SetIndex<S> {
640 type Index = Set<members::index>;
641 type Features = S::Features;
642 }
643 pub struct SetFeatures<S: State = Empty>(PhantomData<fn() -> S>);
645 impl<S: State> sealed::Sealed for SetFeatures<S> {}
646 impl<S: State> State for SetFeatures<S> {
647 type Index = S::Index;
648 type Features = Set<members::features>;
649 }
650 #[allow(non_camel_case_types)]
652 pub mod members {
653 pub struct index(());
655 pub struct features(());
657 }
658}
659
660pub struct FacetBuilder<'a, S: facet_state::State> {
662 _state: PhantomData<fn() -> S>,
663 _fields: (Option<Vec<FacetFeaturesItem<'a>>>, Option<facet::ByteSlice<'a>>),
664 _lifetime: PhantomData<&'a ()>,
665}
666
667impl<'a> Facet<'a> {
668 pub fn new() -> FacetBuilder<'a, facet_state::Empty> {
670 FacetBuilder::new()
671 }
672}
673
674impl<'a> FacetBuilder<'a, facet_state::Empty> {
675 pub fn new() -> Self {
677 FacetBuilder {
678 _state: PhantomData,
679 _fields: (None, None),
680 _lifetime: PhantomData,
681 }
682 }
683}
684
685impl<'a, S> FacetBuilder<'a, S>
686where
687 S: facet_state::State,
688 S::Features: facet_state::IsUnset,
689{
690 pub fn features(
692 mut self,
693 value: impl Into<Vec<FacetFeaturesItem<'a>>>,
694 ) -> FacetBuilder<'a, facet_state::SetFeatures<S>> {
695 self._fields.0 = Option::Some(value.into());
696 FacetBuilder {
697 _state: PhantomData,
698 _fields: self._fields,
699 _lifetime: PhantomData,
700 }
701 }
702}
703
704impl<'a, S> FacetBuilder<'a, S>
705where
706 S: facet_state::State,
707 S::Index: facet_state::IsUnset,
708{
709 pub fn index(
711 mut self,
712 value: impl Into<facet::ByteSlice<'a>>,
713 ) -> FacetBuilder<'a, facet_state::SetIndex<S>> {
714 self._fields.1 = Option::Some(value.into());
715 FacetBuilder {
716 _state: PhantomData,
717 _fields: self._fields,
718 _lifetime: PhantomData,
719 }
720 }
721}
722
723impl<'a, S> FacetBuilder<'a, S>
724where
725 S: facet_state::State,
726 S::Index: facet_state::IsSet,
727 S::Features: facet_state::IsSet,
728{
729 pub fn build(self) -> Facet<'a> {
731 Facet {
732 features: self._fields.0.unwrap(),
733 index: self._fields.1.unwrap(),
734 extra_data: Default::default(),
735 }
736 }
737 pub fn build_with_data(
739 self,
740 extra_data: BTreeMap<
741 jacquard_common::deps::smol_str::SmolStr,
742 jacquard_common::types::value::Data<'a>,
743 >,
744 ) -> Facet<'a> {
745 Facet {
746 features: self._fields.0.unwrap(),
747 index: self._fields.1.unwrap(),
748 extra_data: Some(extra_data),
749 }
750 }
751}
752
753pub mod mention_state {
754
755 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
756 #[allow(unused)]
757 use ::core::marker::PhantomData;
758 mod sealed {
759 pub trait Sealed {}
760 }
761 pub trait State: sealed::Sealed {
763 type Did;
764 }
765 pub struct Empty(());
767 impl sealed::Sealed for Empty {}
768 impl State for Empty {
769 type Did = Unset;
770 }
771 pub struct SetDid<S: State = Empty>(PhantomData<fn() -> S>);
773 impl<S: State> sealed::Sealed for SetDid<S> {}
774 impl<S: State> State for SetDid<S> {
775 type Did = Set<members::did>;
776 }
777 #[allow(non_camel_case_types)]
779 pub mod members {
780 pub struct did(());
782 }
783}
784
785pub struct MentionBuilder<'a, S: mention_state::State> {
787 _state: PhantomData<fn() -> S>,
788 _fields: (Option<Did<'a>>,),
789 _lifetime: PhantomData<&'a ()>,
790}
791
792impl<'a> Mention<'a> {
793 pub fn new() -> MentionBuilder<'a, mention_state::Empty> {
795 MentionBuilder::new()
796 }
797}
798
799impl<'a> MentionBuilder<'a, mention_state::Empty> {
800 pub fn new() -> Self {
802 MentionBuilder {
803 _state: PhantomData,
804 _fields: (None,),
805 _lifetime: PhantomData,
806 }
807 }
808}
809
810impl<'a, S> MentionBuilder<'a, S>
811where
812 S: mention_state::State,
813 S::Did: mention_state::IsUnset,
814{
815 pub fn did(
817 mut self,
818 value: impl Into<Did<'a>>,
819 ) -> MentionBuilder<'a, mention_state::SetDid<S>> {
820 self._fields.0 = Option::Some(value.into());
821 MentionBuilder {
822 _state: PhantomData,
823 _fields: self._fields,
824 _lifetime: PhantomData,
825 }
826 }
827}
828
829impl<'a, S> MentionBuilder<'a, S>
830where
831 S: mention_state::State,
832 S::Did: mention_state::IsSet,
833{
834 pub fn build(self) -> Mention<'a> {
836 Mention {
837 did: self._fields.0.unwrap(),
838 extra_data: Default::default(),
839 }
840 }
841 pub fn build_with_data(
843 self,
844 extra_data: BTreeMap<
845 jacquard_common::deps::smol_str::SmolStr,
846 jacquard_common::types::value::Data<'a>,
847 >,
848 ) -> Mention<'a> {
849 Mention {
850 did: self._fields.0.unwrap(),
851 extra_data: Some(extra_data),
852 }
853 }
854}