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::blob::BlobRef;
18use jacquard_common::types::collection::{Collection, RecordError};
19use jacquard_common::types::string::{AtUri, Cid, Datetime};
20use jacquard_common::types::uri::{RecordUri, UriError};
21use jacquard_common::xrpc::XrpcResp;
22use jacquard_derive::{IntoStatic, lexicon, open_union};
23use jacquard_lexicon::lexicon::LexiconDoc;
24use jacquard_lexicon::schema::LexiconSchema;
25
26#[allow(unused_imports)]
27use jacquard_lexicon::validation::{ConstraintError, ValidationPath};
28use serde::{Serialize, Deserialize};
29use crate::network_slices::tools::richtext::facet::Facet;
30use crate::network_slices::tools::document;
31#[lexicon]
34#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
35#[serde(rename_all = "camelCase")]
36pub struct CodeBlock<'a> {
37 #[serde(borrow)]
38 pub code: CowStr<'a>,
39 #[serde(skip_serializing_if = "Option::is_none")]
40 #[serde(borrow)]
41 pub lang: Option<CowStr<'a>>,
42}
43
44#[lexicon]
47#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
48#[serde(rename_all = "camelCase")]
49pub struct Heading<'a> {
50 #[serde(skip_serializing_if = "Option::is_none")]
51 #[serde(borrow)]
52 pub facets: Option<Vec<Facet<'a>>>,
53 pub level: i64,
54 #[serde(borrow)]
55 pub text: CowStr<'a>,
56}
57
58#[lexicon]
61#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
62#[serde(rename_all = "camelCase")]
63pub struct ImageEmbed<'a> {
64 #[serde(skip_serializing_if = "Option::is_none")]
66 #[serde(borrow)]
67 pub alt: Option<CowStr<'a>>,
68 #[serde(borrow)]
69 pub image: BlobRef<'a>,
70}
71
72
73#[lexicon]
74#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
75#[serde(
76 rename_all = "camelCase",
77 rename = "network.slices.tools.document",
78 tag = "$type"
79)]
80pub struct Document<'a> {
81 #[serde(borrow)]
83 pub blocks: Vec<DocumentBlocksItem<'a>>,
84 pub created_at: Datetime,
85 #[serde(borrow)]
87 pub slug: CowStr<'a>,
88 #[serde(borrow)]
90 pub title: CowStr<'a>,
91 #[serde(skip_serializing_if = "Option::is_none")]
92 pub updated_at: Option<Datetime>,
93}
94
95
96#[open_union]
97#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
98#[serde(tag = "$type", bound(deserialize = "'de: 'a"))]
99pub enum DocumentBlocksItem<'a> {
100 #[serde(rename = "network.slices.tools.document#paragraph")]
101 Paragraph(Box<document::Paragraph<'a>>),
102 #[serde(rename = "network.slices.tools.document#heading")]
103 Heading(Box<document::Heading<'a>>),
104 #[serde(rename = "network.slices.tools.document#codeBlock")]
105 CodeBlock(Box<document::CodeBlock<'a>>),
106 #[serde(rename = "network.slices.tools.document#quote")]
107 Quote(Box<document::Quote<'a>>),
108 #[serde(rename = "network.slices.tools.document#tangledEmbed")]
109 TangledEmbed(Box<document::TangledEmbed<'a>>),
110 #[serde(rename = "network.slices.tools.document#imageEmbed")]
111 ImageEmbed(Box<document::ImageEmbed<'a>>),
112}
113
114#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
117#[serde(rename_all = "camelCase")]
118pub struct DocumentGetRecordOutput<'a> {
119 #[serde(skip_serializing_if = "Option::is_none")]
120 #[serde(borrow)]
121 pub cid: Option<Cid<'a>>,
122 #[serde(borrow)]
123 pub uri: AtUri<'a>,
124 #[serde(borrow)]
125 pub value: Document<'a>,
126}
127
128#[lexicon]
131#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
132#[serde(rename_all = "camelCase")]
133pub struct Paragraph<'a> {
134 #[serde(skip_serializing_if = "Option::is_none")]
135 #[serde(borrow)]
136 pub facets: Option<Vec<Facet<'a>>>,
137 #[serde(borrow)]
138 pub text: CowStr<'a>,
139}
140
141#[lexicon]
144#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
145#[serde(rename_all = "camelCase")]
146pub struct Quote<'a> {
147 #[serde(skip_serializing_if = "Option::is_none")]
148 #[serde(borrow)]
149 pub facets: Option<Vec<Facet<'a>>>,
150 #[serde(borrow)]
151 pub text: CowStr<'a>,
152}
153
154#[lexicon]
157#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
158#[serde(rename_all = "camelCase")]
159pub struct TangledEmbed<'a> {
160 #[serde(borrow)]
162 pub handle: CowStr<'a>,
163 #[serde(borrow)]
165 pub repo: CowStr<'a>,
166}
167
168impl<'a> Document<'a> {
169 pub fn uri(
170 uri: impl Into<CowStr<'a>>,
171 ) -> Result<RecordUri<'a, DocumentRecord>, UriError> {
172 RecordUri::try_from_uri(AtUri::new_cow(uri.into())?)
173 }
174}
175
176impl<'a> LexiconSchema for CodeBlock<'a> {
177 fn nsid() -> &'static str {
178 "network.slices.tools.document"
179 }
180 fn def_name() -> &'static str {
181 "codeBlock"
182 }
183 fn lexicon_doc() -> LexiconDoc<'static> {
184 lexicon_doc_network_slices_tools_document()
185 }
186 fn validate(&self) -> Result<(), ConstraintError> {
187 {
188 let value = &self.code;
189 #[allow(unused_comparisons)]
190 if <str>::len(value.as_ref()) > 20000usize {
191 return Err(ConstraintError::MaxLength {
192 path: ValidationPath::from_field("code"),
193 max: 20000usize,
194 actual: <str>::len(value.as_ref()),
195 });
196 }
197 }
198 if let Some(ref value) = self.lang {
199 #[allow(unused_comparisons)]
200 if <str>::len(value.as_ref()) > 50usize {
201 return Err(ConstraintError::MaxLength {
202 path: ValidationPath::from_field("lang"),
203 max: 50usize,
204 actual: <str>::len(value.as_ref()),
205 });
206 }
207 }
208 Ok(())
209 }
210}
211
212impl<'a> LexiconSchema for Heading<'a> {
213 fn nsid() -> &'static str {
214 "network.slices.tools.document"
215 }
216 fn def_name() -> &'static str {
217 "heading"
218 }
219 fn lexicon_doc() -> LexiconDoc<'static> {
220 lexicon_doc_network_slices_tools_document()
221 }
222 fn validate(&self) -> Result<(), ConstraintError> {
223 {
224 let value = &self.level;
225 if *value > 3i64 {
226 return Err(ConstraintError::Maximum {
227 path: ValidationPath::from_field("level"),
228 max: 3i64,
229 actual: *value,
230 });
231 }
232 }
233 {
234 let value = &self.level;
235 if *value < 1i64 {
236 return Err(ConstraintError::Minimum {
237 path: ValidationPath::from_field("level"),
238 min: 1i64,
239 actual: *value,
240 });
241 }
242 }
243 {
244 let value = &self.text;
245 #[allow(unused_comparisons)]
246 if <str>::len(value.as_ref()) > 300usize {
247 return Err(ConstraintError::MaxLength {
248 path: ValidationPath::from_field("text"),
249 max: 300usize,
250 actual: <str>::len(value.as_ref()),
251 });
252 }
253 }
254 Ok(())
255 }
256}
257
258impl<'a> LexiconSchema for ImageEmbed<'a> {
259 fn nsid() -> &'static str {
260 "network.slices.tools.document"
261 }
262 fn def_name() -> &'static str {
263 "imageEmbed"
264 }
265 fn lexicon_doc() -> LexiconDoc<'static> {
266 lexicon_doc_network_slices_tools_document()
267 }
268 fn validate(&self) -> Result<(), ConstraintError> {
269 if let Some(ref value) = self.alt {
270 #[allow(unused_comparisons)]
271 if <str>::len(value.as_ref()) > 1000usize {
272 return Err(ConstraintError::MaxLength {
273 path: ValidationPath::from_field("alt"),
274 max: 1000usize,
275 actual: <str>::len(value.as_ref()),
276 });
277 }
278 }
279 {
280 let value = &self.image;
281 {
282 let size = value.blob().size;
283 if size > 1000000usize {
284 return Err(ConstraintError::BlobTooLarge {
285 path: ValidationPath::from_field("image"),
286 max: 1000000usize,
287 actual: size,
288 });
289 }
290 }
291 }
292 {
293 let value = &self.image;
294 {
295 let mime = value.blob().mime_type.as_str();
296 let accepted: &[&str] = &["image/*"];
297 let matched = accepted
298 .iter()
299 .any(|pattern| {
300 if *pattern == "*/*" {
301 true
302 } else if pattern.ends_with("/*") {
303 let prefix = &pattern[..pattern.len() - 2];
304 mime.starts_with(prefix)
305 && mime.as_bytes().get(prefix.len()) == Some(&b'/')
306 } else {
307 mime == *pattern
308 }
309 });
310 if !matched {
311 return Err(ConstraintError::BlobMimeTypeNotAccepted {
312 path: ValidationPath::from_field("image"),
313 accepted: vec!["image/*".to_string()],
314 actual: mime.to_string(),
315 });
316 }
317 }
318 }
319 Ok(())
320 }
321}
322
323#[derive(Debug, Serialize, Deserialize)]
326pub struct DocumentRecord;
327impl XrpcResp for DocumentRecord {
328 const NSID: &'static str = "network.slices.tools.document";
329 const ENCODING: &'static str = "application/json";
330 type Output<'de> = DocumentGetRecordOutput<'de>;
331 type Err<'de> = RecordError<'de>;
332}
333
334impl From<DocumentGetRecordOutput<'_>> for Document<'_> {
335 fn from(output: DocumentGetRecordOutput<'_>) -> Self {
336 use jacquard_common::IntoStatic;
337 output.value.into_static()
338 }
339}
340
341impl Collection for Document<'_> {
342 const NSID: &'static str = "network.slices.tools.document";
343 type Record = DocumentRecord;
344}
345
346impl Collection for DocumentRecord {
347 const NSID: &'static str = "network.slices.tools.document";
348 type Record = DocumentRecord;
349}
350
351impl<'a> LexiconSchema for Document<'a> {
352 fn nsid() -> &'static str {
353 "network.slices.tools.document"
354 }
355 fn def_name() -> &'static str {
356 "main"
357 }
358 fn lexicon_doc() -> LexiconDoc<'static> {
359 lexicon_doc_network_slices_tools_document()
360 }
361 fn validate(&self) -> Result<(), ConstraintError> {
362 {
363 let value = &self.slug;
364 #[allow(unused_comparisons)]
365 if <str>::len(value.as_ref()) > 100usize {
366 return Err(ConstraintError::MaxLength {
367 path: ValidationPath::from_field("slug"),
368 max: 100usize,
369 actual: <str>::len(value.as_ref()),
370 });
371 }
372 }
373 {
374 let value = &self.title;
375 #[allow(unused_comparisons)]
376 if <str>::len(value.as_ref()) > 300usize {
377 return Err(ConstraintError::MaxLength {
378 path: ValidationPath::from_field("title"),
379 max: 300usize,
380 actual: <str>::len(value.as_ref()),
381 });
382 }
383 }
384 Ok(())
385 }
386}
387
388impl<'a> LexiconSchema for Paragraph<'a> {
389 fn nsid() -> &'static str {
390 "network.slices.tools.document"
391 }
392 fn def_name() -> &'static str {
393 "paragraph"
394 }
395 fn lexicon_doc() -> LexiconDoc<'static> {
396 lexicon_doc_network_slices_tools_document()
397 }
398 fn validate(&self) -> Result<(), ConstraintError> {
399 {
400 let value = &self.text;
401 #[allow(unused_comparisons)]
402 if <str>::len(value.as_ref()) > 10000usize {
403 return Err(ConstraintError::MaxLength {
404 path: ValidationPath::from_field("text"),
405 max: 10000usize,
406 actual: <str>::len(value.as_ref()),
407 });
408 }
409 }
410 Ok(())
411 }
412}
413
414impl<'a> LexiconSchema for Quote<'a> {
415 fn nsid() -> &'static str {
416 "network.slices.tools.document"
417 }
418 fn def_name() -> &'static str {
419 "quote"
420 }
421 fn lexicon_doc() -> LexiconDoc<'static> {
422 lexicon_doc_network_slices_tools_document()
423 }
424 fn validate(&self) -> Result<(), ConstraintError> {
425 {
426 let value = &self.text;
427 #[allow(unused_comparisons)]
428 if <str>::len(value.as_ref()) > 5000usize {
429 return Err(ConstraintError::MaxLength {
430 path: ValidationPath::from_field("text"),
431 max: 5000usize,
432 actual: <str>::len(value.as_ref()),
433 });
434 }
435 }
436 Ok(())
437 }
438}
439
440impl<'a> LexiconSchema for TangledEmbed<'a> {
441 fn nsid() -> &'static str {
442 "network.slices.tools.document"
443 }
444 fn def_name() -> &'static str {
445 "tangledEmbed"
446 }
447 fn lexicon_doc() -> LexiconDoc<'static> {
448 lexicon_doc_network_slices_tools_document()
449 }
450 fn validate(&self) -> Result<(), ConstraintError> {
451 {
452 let value = &self.handle;
453 #[allow(unused_comparisons)]
454 if <str>::len(value.as_ref()) > 300usize {
455 return Err(ConstraintError::MaxLength {
456 path: ValidationPath::from_field("handle"),
457 max: 300usize,
458 actual: <str>::len(value.as_ref()),
459 });
460 }
461 }
462 {
463 let value = &self.repo;
464 #[allow(unused_comparisons)]
465 if <str>::len(value.as_ref()) > 300usize {
466 return Err(ConstraintError::MaxLength {
467 path: ValidationPath::from_field("repo"),
468 max: 300usize,
469 actual: <str>::len(value.as_ref()),
470 });
471 }
472 }
473 Ok(())
474 }
475}
476
477fn lexicon_doc_network_slices_tools_document() -> LexiconDoc<'static> {
478 #[allow(unused_imports)]
479 use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
480 use jacquard_lexicon::lexicon::*;
481 use alloc::collections::BTreeMap;
482 LexiconDoc {
483 lexicon: Lexicon::Lexicon1,
484 id: CowStr::new_static("network.slices.tools.document"),
485 defs: {
486 let mut map = BTreeMap::new();
487 map.insert(
488 SmolStr::new_static("codeBlock"),
489 LexUserType::Object(LexObject {
490 description: Some(CowStr::new_static("A fenced code block")),
491 required: Some(vec![SmolStr::new_static("code")]),
492 properties: {
493 #[allow(unused_mut)]
494 let mut map = BTreeMap::new();
495 map.insert(
496 SmolStr::new_static("code"),
497 LexObjectProperty::String(LexString {
498 max_length: Some(20000usize),
499 ..Default::default()
500 }),
501 );
502 map.insert(
503 SmolStr::new_static("lang"),
504 LexObjectProperty::String(LexString {
505 max_length: Some(50usize),
506 ..Default::default()
507 }),
508 );
509 map
510 },
511 ..Default::default()
512 }),
513 );
514 map.insert(
515 SmolStr::new_static("heading"),
516 LexUserType::Object(LexObject {
517 description: Some(
518 CowStr::new_static(
519 "A heading block (h1-h3) with optional inline formatting",
520 ),
521 ),
522 required: Some(
523 vec![SmolStr::new_static("level"), SmolStr::new_static("text")],
524 ),
525 properties: {
526 #[allow(unused_mut)]
527 let mut map = BTreeMap::new();
528 map.insert(
529 SmolStr::new_static("facets"),
530 LexObjectProperty::Array(LexArray {
531 items: LexArrayItem::Ref(LexRef {
532 r#ref: CowStr::new_static(
533 "network.slices.tools.richtext.facet",
534 ),
535 ..Default::default()
536 }),
537 ..Default::default()
538 }),
539 );
540 map.insert(
541 SmolStr::new_static("level"),
542 LexObjectProperty::Integer(LexInteger {
543 minimum: Some(1i64),
544 maximum: Some(3i64),
545 ..Default::default()
546 }),
547 );
548 map.insert(
549 SmolStr::new_static("text"),
550 LexObjectProperty::String(LexString {
551 max_length: Some(300usize),
552 ..Default::default()
553 }),
554 );
555 map
556 },
557 ..Default::default()
558 }),
559 );
560 map.insert(
561 SmolStr::new_static("imageEmbed"),
562 LexUserType::Object(LexObject {
563 description: Some(
564 CowStr::new_static("An embedded image with alt text"),
565 ),
566 required: Some(vec![SmolStr::new_static("image")]),
567 properties: {
568 #[allow(unused_mut)]
569 let mut map = BTreeMap::new();
570 map.insert(
571 SmolStr::new_static("alt"),
572 LexObjectProperty::String(LexString {
573 description: Some(
574 CowStr::new_static("Alt text for accessibility"),
575 ),
576 max_length: Some(1000usize),
577 ..Default::default()
578 }),
579 );
580 map.insert(
581 SmolStr::new_static("image"),
582 LexObjectProperty::Blob(LexBlob { ..Default::default() }),
583 );
584 map
585 },
586 ..Default::default()
587 }),
588 );
589 map.insert(
590 SmolStr::new_static("main"),
591 LexUserType::Record(LexRecord {
592 key: Some(CowStr::new_static("tid")),
593 record: LexRecordRecord::Object(LexObject {
594 required: Some(
595 vec![
596 SmolStr::new_static("title"), SmolStr::new_static("slug"),
597 SmolStr::new_static("blocks"),
598 SmolStr::new_static("createdAt")
599 ],
600 ),
601 properties: {
602 #[allow(unused_mut)]
603 let mut map = BTreeMap::new();
604 map.insert(
605 SmolStr::new_static("blocks"),
606 LexObjectProperty::Array(LexArray {
607 description: Some(
608 CowStr::new_static("Document content as array of blocks"),
609 ),
610 items: LexArrayItem::Union(LexRefUnion {
611 refs: vec![
612 CowStr::new_static("#paragraph"),
613 CowStr::new_static("#heading"),
614 CowStr::new_static("#codeBlock"),
615 CowStr::new_static("#quote"),
616 CowStr::new_static("#tangledEmbed"),
617 CowStr::new_static("#imageEmbed")
618 ],
619 ..Default::default()
620 }),
621 ..Default::default()
622 }),
623 );
624 map.insert(
625 SmolStr::new_static("createdAt"),
626 LexObjectProperty::String(LexString {
627 format: Some(LexStringFormat::Datetime),
628 ..Default::default()
629 }),
630 );
631 map.insert(
632 SmolStr::new_static("slug"),
633 LexObjectProperty::String(LexString {
634 description: Some(
635 CowStr::new_static(
636 "URL-friendly identifier, unique per author",
637 ),
638 ),
639 max_length: Some(100usize),
640 ..Default::default()
641 }),
642 );
643 map.insert(
644 SmolStr::new_static("title"),
645 LexObjectProperty::String(LexString {
646 description: Some(CowStr::new_static("Document title")),
647 max_length: Some(300usize),
648 ..Default::default()
649 }),
650 );
651 map.insert(
652 SmolStr::new_static("updatedAt"),
653 LexObjectProperty::String(LexString {
654 format: Some(LexStringFormat::Datetime),
655 ..Default::default()
656 }),
657 );
658 map
659 },
660 ..Default::default()
661 }),
662 ..Default::default()
663 }),
664 );
665 map.insert(
666 SmolStr::new_static("paragraph"),
667 LexUserType::Object(LexObject {
668 description: Some(
669 CowStr::new_static(
670 "A paragraph block with optional inline formatting",
671 ),
672 ),
673 required: Some(vec![SmolStr::new_static("text")]),
674 properties: {
675 #[allow(unused_mut)]
676 let mut map = BTreeMap::new();
677 map.insert(
678 SmolStr::new_static("facets"),
679 LexObjectProperty::Array(LexArray {
680 items: LexArrayItem::Ref(LexRef {
681 r#ref: CowStr::new_static(
682 "network.slices.tools.richtext.facet",
683 ),
684 ..Default::default()
685 }),
686 ..Default::default()
687 }),
688 );
689 map.insert(
690 SmolStr::new_static("text"),
691 LexObjectProperty::String(LexString {
692 max_length: Some(10000usize),
693 ..Default::default()
694 }),
695 );
696 map
697 },
698 ..Default::default()
699 }),
700 );
701 map.insert(
702 SmolStr::new_static("quote"),
703 LexUserType::Object(LexObject {
704 description: Some(
705 CowStr::new_static(
706 "A blockquote with optional inline formatting",
707 ),
708 ),
709 required: Some(vec![SmolStr::new_static("text")]),
710 properties: {
711 #[allow(unused_mut)]
712 let mut map = BTreeMap::new();
713 map.insert(
714 SmolStr::new_static("facets"),
715 LexObjectProperty::Array(LexArray {
716 items: LexArrayItem::Ref(LexRef {
717 r#ref: CowStr::new_static(
718 "network.slices.tools.richtext.facet",
719 ),
720 ..Default::default()
721 }),
722 ..Default::default()
723 }),
724 );
725 map.insert(
726 SmolStr::new_static("text"),
727 LexObjectProperty::String(LexString {
728 max_length: Some(5000usize),
729 ..Default::default()
730 }),
731 );
732 map
733 },
734 ..Default::default()
735 }),
736 );
737 map.insert(
738 SmolStr::new_static("tangledEmbed"),
739 LexUserType::Object(LexObject {
740 description: Some(
741 CowStr::new_static("An embedded Tangled repo card"),
742 ),
743 required: Some(
744 vec![SmolStr::new_static("handle"), SmolStr::new_static("repo")],
745 ),
746 properties: {
747 #[allow(unused_mut)]
748 let mut map = BTreeMap::new();
749 map.insert(
750 SmolStr::new_static("handle"),
751 LexObjectProperty::String(LexString {
752 description: Some(
753 CowStr::new_static("The repo owner's handle"),
754 ),
755 max_length: Some(300usize),
756 ..Default::default()
757 }),
758 );
759 map.insert(
760 SmolStr::new_static("repo"),
761 LexObjectProperty::String(LexString {
762 description: Some(
763 CowStr::new_static("The repository name"),
764 ),
765 max_length: Some(300usize),
766 ..Default::default()
767 }),
768 );
769 map
770 },
771 ..Default::default()
772 }),
773 );
774 map
775 },
776 ..Default::default()
777 }
778}
779
780pub mod heading_state {
781
782 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
783 #[allow(unused)]
784 use ::core::marker::PhantomData;
785 mod sealed {
786 pub trait Sealed {}
787 }
788 pub trait State: sealed::Sealed {
790 type Text;
791 type Level;
792 }
793 pub struct Empty(());
795 impl sealed::Sealed for Empty {}
796 impl State for Empty {
797 type Text = Unset;
798 type Level = Unset;
799 }
800 pub struct SetText<S: State = Empty>(PhantomData<fn() -> S>);
802 impl<S: State> sealed::Sealed for SetText<S> {}
803 impl<S: State> State for SetText<S> {
804 type Text = Set<members::text>;
805 type Level = S::Level;
806 }
807 pub struct SetLevel<S: State = Empty>(PhantomData<fn() -> S>);
809 impl<S: State> sealed::Sealed for SetLevel<S> {}
810 impl<S: State> State for SetLevel<S> {
811 type Text = S::Text;
812 type Level = Set<members::level>;
813 }
814 #[allow(non_camel_case_types)]
816 pub mod members {
817 pub struct text(());
819 pub struct level(());
821 }
822}
823
824pub struct HeadingBuilder<'a, S: heading_state::State> {
826 _state: PhantomData<fn() -> S>,
827 _fields: (Option<Vec<Facet<'a>>>, Option<i64>, Option<CowStr<'a>>),
828 _lifetime: PhantomData<&'a ()>,
829}
830
831impl<'a> Heading<'a> {
832 pub fn new() -> HeadingBuilder<'a, heading_state::Empty> {
834 HeadingBuilder::new()
835 }
836}
837
838impl<'a> HeadingBuilder<'a, heading_state::Empty> {
839 pub fn new() -> Self {
841 HeadingBuilder {
842 _state: PhantomData,
843 _fields: (None, None, None),
844 _lifetime: PhantomData,
845 }
846 }
847}
848
849impl<'a, S: heading_state::State> HeadingBuilder<'a, S> {
850 pub fn facets(mut self, value: impl Into<Option<Vec<Facet<'a>>>>) -> Self {
852 self._fields.0 = value.into();
853 self
854 }
855 pub fn maybe_facets(mut self, value: Option<Vec<Facet<'a>>>) -> Self {
857 self._fields.0 = value;
858 self
859 }
860}
861
862impl<'a, S> HeadingBuilder<'a, S>
863where
864 S: heading_state::State,
865 S::Level: heading_state::IsUnset,
866{
867 pub fn level(
869 mut self,
870 value: impl Into<i64>,
871 ) -> HeadingBuilder<'a, heading_state::SetLevel<S>> {
872 self._fields.1 = Option::Some(value.into());
873 HeadingBuilder {
874 _state: PhantomData,
875 _fields: self._fields,
876 _lifetime: PhantomData,
877 }
878 }
879}
880
881impl<'a, S> HeadingBuilder<'a, S>
882where
883 S: heading_state::State,
884 S::Text: heading_state::IsUnset,
885{
886 pub fn text(
888 mut self,
889 value: impl Into<CowStr<'a>>,
890 ) -> HeadingBuilder<'a, heading_state::SetText<S>> {
891 self._fields.2 = Option::Some(value.into());
892 HeadingBuilder {
893 _state: PhantomData,
894 _fields: self._fields,
895 _lifetime: PhantomData,
896 }
897 }
898}
899
900impl<'a, S> HeadingBuilder<'a, S>
901where
902 S: heading_state::State,
903 S::Text: heading_state::IsSet,
904 S::Level: heading_state::IsSet,
905{
906 pub fn build(self) -> Heading<'a> {
908 Heading {
909 facets: self._fields.0,
910 level: self._fields.1.unwrap(),
911 text: self._fields.2.unwrap(),
912 extra_data: Default::default(),
913 }
914 }
915 pub fn build_with_data(
917 self,
918 extra_data: BTreeMap<
919 jacquard_common::deps::smol_str::SmolStr,
920 jacquard_common::types::value::Data<'a>,
921 >,
922 ) -> Heading<'a> {
923 Heading {
924 facets: self._fields.0,
925 level: self._fields.1.unwrap(),
926 text: self._fields.2.unwrap(),
927 extra_data: Some(extra_data),
928 }
929 }
930}
931
932pub mod image_embed_state {
933
934 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
935 #[allow(unused)]
936 use ::core::marker::PhantomData;
937 mod sealed {
938 pub trait Sealed {}
939 }
940 pub trait State: sealed::Sealed {
942 type Image;
943 }
944 pub struct Empty(());
946 impl sealed::Sealed for Empty {}
947 impl State for Empty {
948 type Image = Unset;
949 }
950 pub struct SetImage<S: State = Empty>(PhantomData<fn() -> S>);
952 impl<S: State> sealed::Sealed for SetImage<S> {}
953 impl<S: State> State for SetImage<S> {
954 type Image = Set<members::image>;
955 }
956 #[allow(non_camel_case_types)]
958 pub mod members {
959 pub struct image(());
961 }
962}
963
964pub struct ImageEmbedBuilder<'a, S: image_embed_state::State> {
966 _state: PhantomData<fn() -> S>,
967 _fields: (Option<CowStr<'a>>, Option<BlobRef<'a>>),
968 _lifetime: PhantomData<&'a ()>,
969}
970
971impl<'a> ImageEmbed<'a> {
972 pub fn new() -> ImageEmbedBuilder<'a, image_embed_state::Empty> {
974 ImageEmbedBuilder::new()
975 }
976}
977
978impl<'a> ImageEmbedBuilder<'a, image_embed_state::Empty> {
979 pub fn new() -> Self {
981 ImageEmbedBuilder {
982 _state: PhantomData,
983 _fields: (None, None),
984 _lifetime: PhantomData,
985 }
986 }
987}
988
989impl<'a, S: image_embed_state::State> ImageEmbedBuilder<'a, S> {
990 pub fn alt(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
992 self._fields.0 = value.into();
993 self
994 }
995 pub fn maybe_alt(mut self, value: Option<CowStr<'a>>) -> Self {
997 self._fields.0 = value;
998 self
999 }
1000}
1001
1002impl<'a, S> ImageEmbedBuilder<'a, S>
1003where
1004 S: image_embed_state::State,
1005 S::Image: image_embed_state::IsUnset,
1006{
1007 pub fn image(
1009 mut self,
1010 value: impl Into<BlobRef<'a>>,
1011 ) -> ImageEmbedBuilder<'a, image_embed_state::SetImage<S>> {
1012 self._fields.1 = Option::Some(value.into());
1013 ImageEmbedBuilder {
1014 _state: PhantomData,
1015 _fields: self._fields,
1016 _lifetime: PhantomData,
1017 }
1018 }
1019}
1020
1021impl<'a, S> ImageEmbedBuilder<'a, S>
1022where
1023 S: image_embed_state::State,
1024 S::Image: image_embed_state::IsSet,
1025{
1026 pub fn build(self) -> ImageEmbed<'a> {
1028 ImageEmbed {
1029 alt: self._fields.0,
1030 image: self._fields.1.unwrap(),
1031 extra_data: Default::default(),
1032 }
1033 }
1034 pub fn build_with_data(
1036 self,
1037 extra_data: BTreeMap<
1038 jacquard_common::deps::smol_str::SmolStr,
1039 jacquard_common::types::value::Data<'a>,
1040 >,
1041 ) -> ImageEmbed<'a> {
1042 ImageEmbed {
1043 alt: self._fields.0,
1044 image: self._fields.1.unwrap(),
1045 extra_data: Some(extra_data),
1046 }
1047 }
1048}
1049
1050pub mod document_state {
1051
1052 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
1053 #[allow(unused)]
1054 use ::core::marker::PhantomData;
1055 mod sealed {
1056 pub trait Sealed {}
1057 }
1058 pub trait State: sealed::Sealed {
1060 type Blocks;
1061 type Slug;
1062 type CreatedAt;
1063 type Title;
1064 }
1065 pub struct Empty(());
1067 impl sealed::Sealed for Empty {}
1068 impl State for Empty {
1069 type Blocks = Unset;
1070 type Slug = Unset;
1071 type CreatedAt = Unset;
1072 type Title = Unset;
1073 }
1074 pub struct SetBlocks<S: State = Empty>(PhantomData<fn() -> S>);
1076 impl<S: State> sealed::Sealed for SetBlocks<S> {}
1077 impl<S: State> State for SetBlocks<S> {
1078 type Blocks = Set<members::blocks>;
1079 type Slug = S::Slug;
1080 type CreatedAt = S::CreatedAt;
1081 type Title = S::Title;
1082 }
1083 pub struct SetSlug<S: State = Empty>(PhantomData<fn() -> S>);
1085 impl<S: State> sealed::Sealed for SetSlug<S> {}
1086 impl<S: State> State for SetSlug<S> {
1087 type Blocks = S::Blocks;
1088 type Slug = Set<members::slug>;
1089 type CreatedAt = S::CreatedAt;
1090 type Title = S::Title;
1091 }
1092 pub struct SetCreatedAt<S: State = Empty>(PhantomData<fn() -> S>);
1094 impl<S: State> sealed::Sealed for SetCreatedAt<S> {}
1095 impl<S: State> State for SetCreatedAt<S> {
1096 type Blocks = S::Blocks;
1097 type Slug = S::Slug;
1098 type CreatedAt = Set<members::created_at>;
1099 type Title = S::Title;
1100 }
1101 pub struct SetTitle<S: State = Empty>(PhantomData<fn() -> S>);
1103 impl<S: State> sealed::Sealed for SetTitle<S> {}
1104 impl<S: State> State for SetTitle<S> {
1105 type Blocks = S::Blocks;
1106 type Slug = S::Slug;
1107 type CreatedAt = S::CreatedAt;
1108 type Title = Set<members::title>;
1109 }
1110 #[allow(non_camel_case_types)]
1112 pub mod members {
1113 pub struct blocks(());
1115 pub struct slug(());
1117 pub struct created_at(());
1119 pub struct title(());
1121 }
1122}
1123
1124pub struct DocumentBuilder<'a, S: document_state::State> {
1126 _state: PhantomData<fn() -> S>,
1127 _fields: (
1128 Option<Vec<DocumentBlocksItem<'a>>>,
1129 Option<Datetime>,
1130 Option<CowStr<'a>>,
1131 Option<CowStr<'a>>,
1132 Option<Datetime>,
1133 ),
1134 _lifetime: PhantomData<&'a ()>,
1135}
1136
1137impl<'a> Document<'a> {
1138 pub fn new() -> DocumentBuilder<'a, document_state::Empty> {
1140 DocumentBuilder::new()
1141 }
1142}
1143
1144impl<'a> DocumentBuilder<'a, document_state::Empty> {
1145 pub fn new() -> Self {
1147 DocumentBuilder {
1148 _state: PhantomData,
1149 _fields: (None, None, None, None, None),
1150 _lifetime: PhantomData,
1151 }
1152 }
1153}
1154
1155impl<'a, S> DocumentBuilder<'a, S>
1156where
1157 S: document_state::State,
1158 S::Blocks: document_state::IsUnset,
1159{
1160 pub fn blocks(
1162 mut self,
1163 value: impl Into<Vec<DocumentBlocksItem<'a>>>,
1164 ) -> DocumentBuilder<'a, document_state::SetBlocks<S>> {
1165 self._fields.0 = Option::Some(value.into());
1166 DocumentBuilder {
1167 _state: PhantomData,
1168 _fields: self._fields,
1169 _lifetime: PhantomData,
1170 }
1171 }
1172}
1173
1174impl<'a, S> DocumentBuilder<'a, S>
1175where
1176 S: document_state::State,
1177 S::CreatedAt: document_state::IsUnset,
1178{
1179 pub fn created_at(
1181 mut self,
1182 value: impl Into<Datetime>,
1183 ) -> DocumentBuilder<'a, document_state::SetCreatedAt<S>> {
1184 self._fields.1 = Option::Some(value.into());
1185 DocumentBuilder {
1186 _state: PhantomData,
1187 _fields: self._fields,
1188 _lifetime: PhantomData,
1189 }
1190 }
1191}
1192
1193impl<'a, S> DocumentBuilder<'a, S>
1194where
1195 S: document_state::State,
1196 S::Slug: document_state::IsUnset,
1197{
1198 pub fn slug(
1200 mut self,
1201 value: impl Into<CowStr<'a>>,
1202 ) -> DocumentBuilder<'a, document_state::SetSlug<S>> {
1203 self._fields.2 = Option::Some(value.into());
1204 DocumentBuilder {
1205 _state: PhantomData,
1206 _fields: self._fields,
1207 _lifetime: PhantomData,
1208 }
1209 }
1210}
1211
1212impl<'a, S> DocumentBuilder<'a, S>
1213where
1214 S: document_state::State,
1215 S::Title: document_state::IsUnset,
1216{
1217 pub fn title(
1219 mut self,
1220 value: impl Into<CowStr<'a>>,
1221 ) -> DocumentBuilder<'a, document_state::SetTitle<S>> {
1222 self._fields.3 = Option::Some(value.into());
1223 DocumentBuilder {
1224 _state: PhantomData,
1225 _fields: self._fields,
1226 _lifetime: PhantomData,
1227 }
1228 }
1229}
1230
1231impl<'a, S: document_state::State> DocumentBuilder<'a, S> {
1232 pub fn updated_at(mut self, value: impl Into<Option<Datetime>>) -> Self {
1234 self._fields.4 = value.into();
1235 self
1236 }
1237 pub fn maybe_updated_at(mut self, value: Option<Datetime>) -> Self {
1239 self._fields.4 = value;
1240 self
1241 }
1242}
1243
1244impl<'a, S> DocumentBuilder<'a, S>
1245where
1246 S: document_state::State,
1247 S::Blocks: document_state::IsSet,
1248 S::Slug: document_state::IsSet,
1249 S::CreatedAt: document_state::IsSet,
1250 S::Title: document_state::IsSet,
1251{
1252 pub fn build(self) -> Document<'a> {
1254 Document {
1255 blocks: self._fields.0.unwrap(),
1256 created_at: self._fields.1.unwrap(),
1257 slug: self._fields.2.unwrap(),
1258 title: self._fields.3.unwrap(),
1259 updated_at: self._fields.4,
1260 extra_data: Default::default(),
1261 }
1262 }
1263 pub fn build_with_data(
1265 self,
1266 extra_data: BTreeMap<
1267 jacquard_common::deps::smol_str::SmolStr,
1268 jacquard_common::types::value::Data<'a>,
1269 >,
1270 ) -> Document<'a> {
1271 Document {
1272 blocks: self._fields.0.unwrap(),
1273 created_at: self._fields.1.unwrap(),
1274 slug: self._fields.2.unwrap(),
1275 title: self._fields.3.unwrap(),
1276 updated_at: self._fields.4,
1277 extra_data: Some(extra_data),
1278 }
1279 }
1280}