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};
19use jacquard_common::types::uri::{RecordUri, UriError};
20use jacquard_common::xrpc::XrpcResp;
21use jacquard_derive::{IntoStatic, lexicon};
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::pub_leaflet::pages::linear_document::Quote;
29use crate::pub_leaflet::richtext::facet::Facet;
30use crate::pub_leaflet::comment;
31
32#[lexicon]
33#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
34#[serde(rename_all = "camelCase")]
35pub struct LinearDocumentQuote<'a> {
36 #[serde(borrow)]
37 pub document: AtUri<'a>,
38 #[serde(borrow)]
39 pub quote: Quote<'a>,
40}
41
42#[lexicon]
45#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
46#[serde(rename_all = "camelCase", rename = "pub.leaflet.comment", tag = "$type")]
47pub struct Comment<'a> {
48 #[serde(skip_serializing_if = "Option::is_none")]
49 #[serde(borrow)]
50 pub attachment: Option<comment::LinearDocumentQuote<'a>>,
51 pub created_at: Datetime,
52 #[serde(skip_serializing_if = "Option::is_none")]
53 #[serde(borrow)]
54 pub facets: Option<Vec<Facet<'a>>>,
55 #[serde(skip_serializing_if = "Option::is_none")]
56 #[serde(borrow)]
57 pub on_page: Option<CowStr<'a>>,
58 #[serde(borrow)]
59 pub plaintext: CowStr<'a>,
60 #[serde(skip_serializing_if = "Option::is_none")]
61 #[serde(borrow)]
62 pub reply: Option<comment::ReplyRef<'a>>,
63 #[serde(borrow)]
64 pub subject: AtUri<'a>,
65}
66
67#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
70#[serde(rename_all = "camelCase")]
71pub struct CommentGetRecordOutput<'a> {
72 #[serde(skip_serializing_if = "Option::is_none")]
73 #[serde(borrow)]
74 pub cid: Option<Cid<'a>>,
75 #[serde(borrow)]
76 pub uri: AtUri<'a>,
77 #[serde(borrow)]
78 pub value: Comment<'a>,
79}
80
81
82#[lexicon]
83#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
84#[serde(rename_all = "camelCase")]
85pub struct ReplyRef<'a> {
86 #[serde(borrow)]
87 pub parent: AtUri<'a>,
88}
89
90impl<'a> Comment<'a> {
91 pub fn uri(
92 uri: impl Into<CowStr<'a>>,
93 ) -> Result<RecordUri<'a, CommentRecord>, UriError> {
94 RecordUri::try_from_uri(AtUri::new_cow(uri.into())?)
95 }
96}
97
98impl<'a> LexiconSchema for LinearDocumentQuote<'a> {
99 fn nsid() -> &'static str {
100 "pub.leaflet.comment"
101 }
102 fn def_name() -> &'static str {
103 "linearDocumentQuote"
104 }
105 fn lexicon_doc() -> LexiconDoc<'static> {
106 lexicon_doc_pub_leaflet_comment()
107 }
108 fn validate(&self) -> Result<(), ConstraintError> {
109 Ok(())
110 }
111}
112
113#[derive(Debug, Serialize, Deserialize)]
116pub struct CommentRecord;
117impl XrpcResp for CommentRecord {
118 const NSID: &'static str = "pub.leaflet.comment";
119 const ENCODING: &'static str = "application/json";
120 type Output<'de> = CommentGetRecordOutput<'de>;
121 type Err<'de> = RecordError<'de>;
122}
123
124impl From<CommentGetRecordOutput<'_>> for Comment<'_> {
125 fn from(output: CommentGetRecordOutput<'_>) -> Self {
126 use jacquard_common::IntoStatic;
127 output.value.into_static()
128 }
129}
130
131impl Collection for Comment<'_> {
132 const NSID: &'static str = "pub.leaflet.comment";
133 type Record = CommentRecord;
134}
135
136impl Collection for CommentRecord {
137 const NSID: &'static str = "pub.leaflet.comment";
138 type Record = CommentRecord;
139}
140
141impl<'a> LexiconSchema for Comment<'a> {
142 fn nsid() -> &'static str {
143 "pub.leaflet.comment"
144 }
145 fn def_name() -> &'static str {
146 "main"
147 }
148 fn lexicon_doc() -> LexiconDoc<'static> {
149 lexicon_doc_pub_leaflet_comment()
150 }
151 fn validate(&self) -> Result<(), ConstraintError> {
152 Ok(())
153 }
154}
155
156impl<'a> LexiconSchema for ReplyRef<'a> {
157 fn nsid() -> &'static str {
158 "pub.leaflet.comment"
159 }
160 fn def_name() -> &'static str {
161 "replyRef"
162 }
163 fn lexicon_doc() -> LexiconDoc<'static> {
164 lexicon_doc_pub_leaflet_comment()
165 }
166 fn validate(&self) -> Result<(), ConstraintError> {
167 Ok(())
168 }
169}
170
171pub mod linear_document_quote_state {
172
173 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
174 #[allow(unused)]
175 use ::core::marker::PhantomData;
176 mod sealed {
177 pub trait Sealed {}
178 }
179 pub trait State: sealed::Sealed {
181 type Quote;
182 type Document;
183 }
184 pub struct Empty(());
186 impl sealed::Sealed for Empty {}
187 impl State for Empty {
188 type Quote = Unset;
189 type Document = Unset;
190 }
191 pub struct SetQuote<S: State = Empty>(PhantomData<fn() -> S>);
193 impl<S: State> sealed::Sealed for SetQuote<S> {}
194 impl<S: State> State for SetQuote<S> {
195 type Quote = Set<members::quote>;
196 type Document = S::Document;
197 }
198 pub struct SetDocument<S: State = Empty>(PhantomData<fn() -> S>);
200 impl<S: State> sealed::Sealed for SetDocument<S> {}
201 impl<S: State> State for SetDocument<S> {
202 type Quote = S::Quote;
203 type Document = Set<members::document>;
204 }
205 #[allow(non_camel_case_types)]
207 pub mod members {
208 pub struct quote(());
210 pub struct document(());
212 }
213}
214
215pub struct LinearDocumentQuoteBuilder<'a, S: linear_document_quote_state::State> {
217 _state: PhantomData<fn() -> S>,
218 _fields: (Option<AtUri<'a>>, Option<Quote<'a>>),
219 _lifetime: PhantomData<&'a ()>,
220}
221
222impl<'a> LinearDocumentQuote<'a> {
223 pub fn new() -> LinearDocumentQuoteBuilder<'a, linear_document_quote_state::Empty> {
225 LinearDocumentQuoteBuilder::new()
226 }
227}
228
229impl<'a> LinearDocumentQuoteBuilder<'a, linear_document_quote_state::Empty> {
230 pub fn new() -> Self {
232 LinearDocumentQuoteBuilder {
233 _state: PhantomData,
234 _fields: (None, None),
235 _lifetime: PhantomData,
236 }
237 }
238}
239
240impl<'a, S> LinearDocumentQuoteBuilder<'a, S>
241where
242 S: linear_document_quote_state::State,
243 S::Document: linear_document_quote_state::IsUnset,
244{
245 pub fn document(
247 mut self,
248 value: impl Into<AtUri<'a>>,
249 ) -> LinearDocumentQuoteBuilder<'a, linear_document_quote_state::SetDocument<S>> {
250 self._fields.0 = Option::Some(value.into());
251 LinearDocumentQuoteBuilder {
252 _state: PhantomData,
253 _fields: self._fields,
254 _lifetime: PhantomData,
255 }
256 }
257}
258
259impl<'a, S> LinearDocumentQuoteBuilder<'a, S>
260where
261 S: linear_document_quote_state::State,
262 S::Quote: linear_document_quote_state::IsUnset,
263{
264 pub fn quote(
266 mut self,
267 value: impl Into<Quote<'a>>,
268 ) -> LinearDocumentQuoteBuilder<'a, linear_document_quote_state::SetQuote<S>> {
269 self._fields.1 = Option::Some(value.into());
270 LinearDocumentQuoteBuilder {
271 _state: PhantomData,
272 _fields: self._fields,
273 _lifetime: PhantomData,
274 }
275 }
276}
277
278impl<'a, S> LinearDocumentQuoteBuilder<'a, S>
279where
280 S: linear_document_quote_state::State,
281 S::Quote: linear_document_quote_state::IsSet,
282 S::Document: linear_document_quote_state::IsSet,
283{
284 pub fn build(self) -> LinearDocumentQuote<'a> {
286 LinearDocumentQuote {
287 document: self._fields.0.unwrap(),
288 quote: self._fields.1.unwrap(),
289 extra_data: Default::default(),
290 }
291 }
292 pub fn build_with_data(
294 self,
295 extra_data: BTreeMap<
296 jacquard_common::deps::smol_str::SmolStr,
297 jacquard_common::types::value::Data<'a>,
298 >,
299 ) -> LinearDocumentQuote<'a> {
300 LinearDocumentQuote {
301 document: self._fields.0.unwrap(),
302 quote: self._fields.1.unwrap(),
303 extra_data: Some(extra_data),
304 }
305 }
306}
307
308fn lexicon_doc_pub_leaflet_comment() -> LexiconDoc<'static> {
309 #[allow(unused_imports)]
310 use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
311 use jacquard_lexicon::lexicon::*;
312 use alloc::collections::BTreeMap;
313 LexiconDoc {
314 lexicon: Lexicon::Lexicon1,
315 id: CowStr::new_static("pub.leaflet.comment"),
316 defs: {
317 let mut map = BTreeMap::new();
318 map.insert(
319 SmolStr::new_static("linearDocumentQuote"),
320 LexUserType::Object(LexObject {
321 required: Some(
322 vec![
323 SmolStr::new_static("document"), SmolStr::new_static("quote")
324 ],
325 ),
326 properties: {
327 #[allow(unused_mut)]
328 let mut map = BTreeMap::new();
329 map.insert(
330 SmolStr::new_static("document"),
331 LexObjectProperty::String(LexString {
332 format: Some(LexStringFormat::AtUri),
333 ..Default::default()
334 }),
335 );
336 map.insert(
337 SmolStr::new_static("quote"),
338 LexObjectProperty::Ref(LexRef {
339 r#ref: CowStr::new_static(
340 "pub.leaflet.pages.linearDocument#quote",
341 ),
342 ..Default::default()
343 }),
344 );
345 map
346 },
347 ..Default::default()
348 }),
349 );
350 map.insert(
351 SmolStr::new_static("main"),
352 LexUserType::Record(LexRecord {
353 description: Some(CowStr::new_static("Record containing a comment")),
354 key: Some(CowStr::new_static("tid")),
355 record: LexRecordRecord::Object(LexObject {
356 required: Some(
357 vec![
358 SmolStr::new_static("subject"),
359 SmolStr::new_static("plaintext"),
360 SmolStr::new_static("createdAt")
361 ],
362 ),
363 properties: {
364 #[allow(unused_mut)]
365 let mut map = BTreeMap::new();
366 map.insert(
367 SmolStr::new_static("attachment"),
368 LexObjectProperty::Union(LexRefUnion {
369 refs: vec![CowStr::new_static("#linearDocumentQuote")],
370 ..Default::default()
371 }),
372 );
373 map.insert(
374 SmolStr::new_static("createdAt"),
375 LexObjectProperty::String(LexString {
376 format: Some(LexStringFormat::Datetime),
377 ..Default::default()
378 }),
379 );
380 map.insert(
381 SmolStr::new_static("facets"),
382 LexObjectProperty::Array(LexArray {
383 items: LexArrayItem::Ref(LexRef {
384 r#ref: CowStr::new_static("pub.leaflet.richtext.facet"),
385 ..Default::default()
386 }),
387 ..Default::default()
388 }),
389 );
390 map.insert(
391 SmolStr::new_static("onPage"),
392 LexObjectProperty::String(LexString {
393 ..Default::default()
394 }),
395 );
396 map.insert(
397 SmolStr::new_static("plaintext"),
398 LexObjectProperty::String(LexString {
399 ..Default::default()
400 }),
401 );
402 map.insert(
403 SmolStr::new_static("reply"),
404 LexObjectProperty::Ref(LexRef {
405 r#ref: CowStr::new_static("#replyRef"),
406 ..Default::default()
407 }),
408 );
409 map.insert(
410 SmolStr::new_static("subject"),
411 LexObjectProperty::String(LexString {
412 format: Some(LexStringFormat::AtUri),
413 ..Default::default()
414 }),
415 );
416 map
417 },
418 ..Default::default()
419 }),
420 ..Default::default()
421 }),
422 );
423 map.insert(
424 SmolStr::new_static("replyRef"),
425 LexUserType::Object(LexObject {
426 required: Some(vec![SmolStr::new_static("parent")]),
427 properties: {
428 #[allow(unused_mut)]
429 let mut map = BTreeMap::new();
430 map.insert(
431 SmolStr::new_static("parent"),
432 LexObjectProperty::String(LexString {
433 format: Some(LexStringFormat::AtUri),
434 ..Default::default()
435 }),
436 );
437 map
438 },
439 ..Default::default()
440 }),
441 );
442 map
443 },
444 ..Default::default()
445 }
446}
447
448pub mod comment_state {
449
450 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
451 #[allow(unused)]
452 use ::core::marker::PhantomData;
453 mod sealed {
454 pub trait Sealed {}
455 }
456 pub trait State: sealed::Sealed {
458 type Plaintext;
459 type CreatedAt;
460 type Subject;
461 }
462 pub struct Empty(());
464 impl sealed::Sealed for Empty {}
465 impl State for Empty {
466 type Plaintext = Unset;
467 type CreatedAt = Unset;
468 type Subject = Unset;
469 }
470 pub struct SetPlaintext<S: State = Empty>(PhantomData<fn() -> S>);
472 impl<S: State> sealed::Sealed for SetPlaintext<S> {}
473 impl<S: State> State for SetPlaintext<S> {
474 type Plaintext = Set<members::plaintext>;
475 type CreatedAt = S::CreatedAt;
476 type Subject = S::Subject;
477 }
478 pub struct SetCreatedAt<S: State = Empty>(PhantomData<fn() -> S>);
480 impl<S: State> sealed::Sealed for SetCreatedAt<S> {}
481 impl<S: State> State for SetCreatedAt<S> {
482 type Plaintext = S::Plaintext;
483 type CreatedAt = Set<members::created_at>;
484 type Subject = S::Subject;
485 }
486 pub struct SetSubject<S: State = Empty>(PhantomData<fn() -> S>);
488 impl<S: State> sealed::Sealed for SetSubject<S> {}
489 impl<S: State> State for SetSubject<S> {
490 type Plaintext = S::Plaintext;
491 type CreatedAt = S::CreatedAt;
492 type Subject = Set<members::subject>;
493 }
494 #[allow(non_camel_case_types)]
496 pub mod members {
497 pub struct plaintext(());
499 pub struct created_at(());
501 pub struct subject(());
503 }
504}
505
506pub struct CommentBuilder<'a, S: comment_state::State> {
508 _state: PhantomData<fn() -> S>,
509 _fields: (
510 Option<comment::LinearDocumentQuote<'a>>,
511 Option<Datetime>,
512 Option<Vec<Facet<'a>>>,
513 Option<CowStr<'a>>,
514 Option<CowStr<'a>>,
515 Option<comment::ReplyRef<'a>>,
516 Option<AtUri<'a>>,
517 ),
518 _lifetime: PhantomData<&'a ()>,
519}
520
521impl<'a> Comment<'a> {
522 pub fn new() -> CommentBuilder<'a, comment_state::Empty> {
524 CommentBuilder::new()
525 }
526}
527
528impl<'a> CommentBuilder<'a, comment_state::Empty> {
529 pub fn new() -> Self {
531 CommentBuilder {
532 _state: PhantomData,
533 _fields: (None, None, None, None, None, None, None),
534 _lifetime: PhantomData,
535 }
536 }
537}
538
539impl<'a, S: comment_state::State> CommentBuilder<'a, S> {
540 pub fn attachment(
542 mut self,
543 value: impl Into<Option<comment::LinearDocumentQuote<'a>>>,
544 ) -> Self {
545 self._fields.0 = value.into();
546 self
547 }
548 pub fn maybe_attachment(
550 mut self,
551 value: Option<comment::LinearDocumentQuote<'a>>,
552 ) -> Self {
553 self._fields.0 = value;
554 self
555 }
556}
557
558impl<'a, S> CommentBuilder<'a, S>
559where
560 S: comment_state::State,
561 S::CreatedAt: comment_state::IsUnset,
562{
563 pub fn created_at(
565 mut self,
566 value: impl Into<Datetime>,
567 ) -> CommentBuilder<'a, comment_state::SetCreatedAt<S>> {
568 self._fields.1 = Option::Some(value.into());
569 CommentBuilder {
570 _state: PhantomData,
571 _fields: self._fields,
572 _lifetime: PhantomData,
573 }
574 }
575}
576
577impl<'a, S: comment_state::State> CommentBuilder<'a, S> {
578 pub fn facets(mut self, value: impl Into<Option<Vec<Facet<'a>>>>) -> Self {
580 self._fields.2 = value.into();
581 self
582 }
583 pub fn maybe_facets(mut self, value: Option<Vec<Facet<'a>>>) -> Self {
585 self._fields.2 = value;
586 self
587 }
588}
589
590impl<'a, S: comment_state::State> CommentBuilder<'a, S> {
591 pub fn on_page(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
593 self._fields.3 = value.into();
594 self
595 }
596 pub fn maybe_on_page(mut self, value: Option<CowStr<'a>>) -> Self {
598 self._fields.3 = value;
599 self
600 }
601}
602
603impl<'a, S> CommentBuilder<'a, S>
604where
605 S: comment_state::State,
606 S::Plaintext: comment_state::IsUnset,
607{
608 pub fn plaintext(
610 mut self,
611 value: impl Into<CowStr<'a>>,
612 ) -> CommentBuilder<'a, comment_state::SetPlaintext<S>> {
613 self._fields.4 = Option::Some(value.into());
614 CommentBuilder {
615 _state: PhantomData,
616 _fields: self._fields,
617 _lifetime: PhantomData,
618 }
619 }
620}
621
622impl<'a, S: comment_state::State> CommentBuilder<'a, S> {
623 pub fn reply(mut self, value: impl Into<Option<comment::ReplyRef<'a>>>) -> Self {
625 self._fields.5 = value.into();
626 self
627 }
628 pub fn maybe_reply(mut self, value: Option<comment::ReplyRef<'a>>) -> Self {
630 self._fields.5 = value;
631 self
632 }
633}
634
635impl<'a, S> CommentBuilder<'a, S>
636where
637 S: comment_state::State,
638 S::Subject: comment_state::IsUnset,
639{
640 pub fn subject(
642 mut self,
643 value: impl Into<AtUri<'a>>,
644 ) -> CommentBuilder<'a, comment_state::SetSubject<S>> {
645 self._fields.6 = Option::Some(value.into());
646 CommentBuilder {
647 _state: PhantomData,
648 _fields: self._fields,
649 _lifetime: PhantomData,
650 }
651 }
652}
653
654impl<'a, S> CommentBuilder<'a, S>
655where
656 S: comment_state::State,
657 S::Plaintext: comment_state::IsSet,
658 S::CreatedAt: comment_state::IsSet,
659 S::Subject: comment_state::IsSet,
660{
661 pub fn build(self) -> Comment<'a> {
663 Comment {
664 attachment: self._fields.0,
665 created_at: self._fields.1.unwrap(),
666 facets: self._fields.2,
667 on_page: self._fields.3,
668 plaintext: self._fields.4.unwrap(),
669 reply: self._fields.5,
670 subject: self._fields.6.unwrap(),
671 extra_data: Default::default(),
672 }
673 }
674 pub fn build_with_data(
676 self,
677 extra_data: BTreeMap<
678 jacquard_common::deps::smol_str::SmolStr,
679 jacquard_common::types::value::Data<'a>,
680 >,
681 ) -> Comment<'a> {
682 Comment {
683 attachment: self._fields.0,
684 created_at: self._fields.1.unwrap(),
685 facets: self._fields.2,
686 on_page: self._fields.3,
687 plaintext: self._fields.4.unwrap(),
688 reply: self._fields.5,
689 subject: self._fields.6.unwrap(),
690 extra_data: Some(extra_data),
691 }
692 }
693}
694
695pub mod reply_ref_state {
696
697 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
698 #[allow(unused)]
699 use ::core::marker::PhantomData;
700 mod sealed {
701 pub trait Sealed {}
702 }
703 pub trait State: sealed::Sealed {
705 type Parent;
706 }
707 pub struct Empty(());
709 impl sealed::Sealed for Empty {}
710 impl State for Empty {
711 type Parent = Unset;
712 }
713 pub struct SetParent<S: State = Empty>(PhantomData<fn() -> S>);
715 impl<S: State> sealed::Sealed for SetParent<S> {}
716 impl<S: State> State for SetParent<S> {
717 type Parent = Set<members::parent>;
718 }
719 #[allow(non_camel_case_types)]
721 pub mod members {
722 pub struct parent(());
724 }
725}
726
727pub struct ReplyRefBuilder<'a, S: reply_ref_state::State> {
729 _state: PhantomData<fn() -> S>,
730 _fields: (Option<AtUri<'a>>,),
731 _lifetime: PhantomData<&'a ()>,
732}
733
734impl<'a> ReplyRef<'a> {
735 pub fn new() -> ReplyRefBuilder<'a, reply_ref_state::Empty> {
737 ReplyRefBuilder::new()
738 }
739}
740
741impl<'a> ReplyRefBuilder<'a, reply_ref_state::Empty> {
742 pub fn new() -> Self {
744 ReplyRefBuilder {
745 _state: PhantomData,
746 _fields: (None,),
747 _lifetime: PhantomData,
748 }
749 }
750}
751
752impl<'a, S> ReplyRefBuilder<'a, S>
753where
754 S: reply_ref_state::State,
755 S::Parent: reply_ref_state::IsUnset,
756{
757 pub fn parent(
759 mut self,
760 value: impl Into<AtUri<'a>>,
761 ) -> ReplyRefBuilder<'a, reply_ref_state::SetParent<S>> {
762 self._fields.0 = Option::Some(value.into());
763 ReplyRefBuilder {
764 _state: PhantomData,
765 _fields: self._fields,
766 _lifetime: PhantomData,
767 }
768 }
769}
770
771impl<'a, S> ReplyRefBuilder<'a, S>
772where
773 S: reply_ref_state::State,
774 S::Parent: reply_ref_state::IsSet,
775{
776 pub fn build(self) -> ReplyRef<'a> {
778 ReplyRef {
779 parent: self._fields.0.unwrap(),
780 extra_data: Default::default(),
781 }
782 }
783 pub fn build_with_data(
785 self,
786 extra_data: BTreeMap<
787 jacquard_common::deps::smol_str::SmolStr,
788 jacquard_common::types::value::Data<'a>,
789 >,
790 ) -> ReplyRef<'a> {
791 ReplyRef {
792 parent: self._fields.0.unwrap(),
793 extra_data: Some(extra_data),
794 }
795 }
796}