1use serde::{Deserialize, Serialize};
2
3use super::tag::{tagged_enum, Tag, Tagged};
4
5#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
7pub struct RichTextBlock {
8 r#type: Tag<Self>,
9 pub elements: Vec<RichTextObject>,
10 #[serde(skip_serializing_if = "Option::is_none")]
11 pub block_id: Option<String>,
12}
13
14impl Tagged for RichTextBlock {
15 const TAG: &'static str = "rich_text";
16}
17
18impl RichTextBlock {
19 pub fn new(elements: Vec<RichTextObject>) -> Self {
20 Self {
21 r#type: Tag::default(),
22 elements,
23 block_id: None,
24 }
25 }
26
27 pub fn block_id(mut self, block_id: impl Into<String>) -> Self {
28 self.block_id = Some(block_id.into());
29 self
30 }
31}
32
33tagged_enum! {
34 pub enum RichTextObject("type") {
36 Section(RichTextSection),
37 List(RichTextList),
38 Preformatted(RichTextPreformatted),
39 Quote(RichTextQuote),
40 }
41}
42
43#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
45pub struct RichTextSection {
46 r#type: Tag<Self>,
47 pub elements: Vec<RichTextElement>,
48}
49
50impl Tagged for RichTextSection {
51 const TAG: &'static str = "rich_text_section";
52}
53
54impl RichTextSection {
55 pub fn new(elements: Vec<RichTextElement>) -> Self {
56 Self {
57 r#type: Tag::default(),
58 elements,
59 }
60 }
61}
62
63#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
65pub struct RichTextList {
66 r#type: Tag<Self>,
67 pub style: RichTextListStyle,
68 pub elements: Vec<RichTextSection>,
69 #[serde(skip_serializing_if = "Option::is_none")]
70 pub indent: Option<u32>,
71 #[serde(skip_serializing_if = "Option::is_none")]
72 pub offset: Option<u32>,
73 #[serde(skip_serializing_if = "Option::is_none")]
74 pub border: Option<u8>,
75}
76
77impl Tagged for RichTextList {
78 const TAG: &'static str = "rich_text_list";
79}
80
81impl RichTextList {
82 pub fn new(style: RichTextListStyle, elements: Vec<RichTextSection>) -> Self {
83 Self {
84 r#type: Tag::default(),
85 style,
86 elements,
87 indent: None,
88 offset: None,
89 border: None,
90 }
91 }
92
93 pub fn indent(mut self, indent: u32) -> Self {
94 self.indent = Some(indent);
95 self
96 }
97
98 pub fn offset(mut self, offset: u32) -> Self {
99 self.offset = Some(offset);
100 self
101 }
102
103 pub fn border(mut self, border: u8) -> Self {
104 self.border = Some(border);
105 self
106 }
107}
108
109#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
111pub struct RichTextPreformatted {
112 r#type: Tag<Self>,
113 pub elements: Vec<PreformattedElement>,
114 #[serde(skip_serializing_if = "Option::is_none")]
115 pub border: Option<u8>,
116 #[serde(skip_serializing_if = "Option::is_none")]
117 pub language: Option<String>,
118}
119
120impl Tagged for RichTextPreformatted {
121 const TAG: &'static str = "rich_text_preformatted";
122}
123
124impl RichTextPreformatted {
125 pub fn new(elements: Vec<PreformattedElement>) -> Self {
126 Self {
127 r#type: Tag::default(),
128 elements,
129 border: None,
130 language: None,
131 }
132 }
133
134 pub fn border(mut self, border: u8) -> Self {
135 self.border = Some(border);
136 self
137 }
138
139 pub fn language(mut self, language: impl Into<String>) -> Self {
140 self.language = Some(language.into());
141 self
142 }
143}
144
145#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
147pub struct RichTextQuote {
148 r#type: Tag<Self>,
149 pub elements: Vec<RichTextElement>,
150 #[serde(skip_serializing_if = "Option::is_none")]
151 pub border: Option<u8>,
152}
153
154impl Tagged for RichTextQuote {
155 const TAG: &'static str = "rich_text_quote";
156}
157
158impl RichTextQuote {
159 pub fn new(elements: Vec<RichTextElement>) -> Self {
160 Self {
161 r#type: Tag::default(),
162 elements,
163 border: None,
164 }
165 }
166
167 pub fn border(mut self, border: u8) -> Self {
168 self.border = Some(border);
169 self
170 }
171}
172
173tagged_enum! {
174 pub enum PreformattedElement("type") {
176 Text(TextElement),
177 Link(LinkElement),
178 }
179}
180
181tagged_enum! {
182 pub enum RichTextElement("type") {
184 AttachmentMention(AttachmentMentionElement),
185 Broadcast(BroadcastElement),
186 Canvas(CanvasElement),
187 CanvasUserMention(CanvasUserMentionElement),
188 CanvasMessageUnfurl(CanvasMessageUnfurlElement),
189 Channel(ChannelElement),
190 Citation(CitationElement),
191 Color(ColorElement),
192 Date(DateElement),
193 Emoji(EmojiElement),
194 File(FileElement),
195 Link(LinkElement),
196 ListRecord(ListRecordElement),
197 MessageMention(MessageMentionElement),
198 SalesforceDataField(SalesforceDataFieldElement),
199 Tag(TagElement),
200 Team(TeamElement),
201 Text(TextElement),
202 User(UserElement),
203 Usergroup(UsergroupElement),
204 WorkObjectMention(WorkObjectMentionElement),
205 WorkflowMention(WorkflowMentionElement),
206 }
207}
208
209#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
211pub struct RichTextStyle {
212 #[serde(skip_serializing_if = "Option::is_none")]
213 pub bold: Option<bool>,
214 #[serde(skip_serializing_if = "Option::is_none")]
215 pub italic: Option<bool>,
216 #[serde(skip_serializing_if = "Option::is_none")]
217 pub strike: Option<bool>,
218 #[serde(skip_serializing_if = "Option::is_none")]
219 pub highlight: Option<bool>,
220 #[serde(skip_serializing_if = "Option::is_none")]
221 pub client_highlight: Option<bool>,
222 #[serde(skip_serializing_if = "Option::is_none")]
223 pub underline: Option<bool>,
224 #[serde(skip_serializing_if = "Option::is_none")]
225 pub unlink: Option<bool>,
226 #[serde(skip_serializing_if = "Option::is_none")]
227 pub code: Option<bool>,
228}
229
230impl RichTextStyle {
231 pub fn new() -> Self {
232 Self::default()
233 }
234
235 pub fn bold(mut self, bold: bool) -> Self {
236 self.bold = Some(bold);
237 self
238 }
239
240 pub fn italic(mut self, italic: bool) -> Self {
241 self.italic = Some(italic);
242 self
243 }
244
245 pub fn strike(mut self, strike: bool) -> Self {
246 self.strike = Some(strike);
247 self
248 }
249
250 pub fn highlight(mut self, highlight: bool) -> Self {
251 self.highlight = Some(highlight);
252 self
253 }
254
255 pub fn client_highlight(mut self, client_highlight: bool) -> Self {
256 self.client_highlight = Some(client_highlight);
257 self
258 }
259
260 pub fn underline(mut self, underline: bool) -> Self {
261 self.underline = Some(underline);
262 self
263 }
264
265 pub fn unlink(mut self, unlink: bool) -> Self {
266 self.unlink = Some(unlink);
267 self
268 }
269
270 pub fn code(mut self, code: bool) -> Self {
271 self.code = Some(code);
272 self
273 }
274}
275
276#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
278pub struct AttachmentMentionElement {
279 r#type: Tag<Self>,
280 pub url: String,
281 #[serde(skip_serializing_if = "Option::is_none")]
282 pub text: Option<String>,
283 #[serde(skip_serializing_if = "Option::is_none")]
284 pub app_id: Option<String>,
285 #[serde(skip_serializing_if = "Option::is_none")]
286 pub entity_id: Option<String>,
287 #[serde(skip_serializing_if = "Option::is_none")]
288 pub icon_url: Option<String>,
289 #[serde(skip_serializing_if = "Option::is_none")]
290 pub channel_id: Option<String>,
291 #[serde(skip_serializing_if = "Option::is_none")]
292 pub ts: Option<String>,
293 #[serde(skip_serializing_if = "Option::is_none")]
294 pub full_size_preview_enabled: Option<bool>,
295 #[serde(skip_serializing_if = "Option::is_none")]
296 pub icon_name: Option<String>,
297 #[serde(skip_serializing_if = "Option::is_none")]
298 pub reference_object_type: Option<String>,
299 #[serde(skip_serializing_if = "Option::is_none")]
300 pub product_name: Option<String>,
301 #[serde(skip_serializing_if = "Option::is_none")]
302 pub style: Option<RichTextStyle>,
303}
304
305impl Tagged for AttachmentMentionElement {
306 const TAG: &'static str = "attachment_mention";
307}
308
309impl AttachmentMentionElement {
310 pub fn new(url: impl Into<String>) -> Self {
311 Self {
312 r#type: Tag::default(),
313 url: url.into(),
314 text: None,
315 app_id: None,
316 entity_id: None,
317 icon_url: None,
318 channel_id: None,
319 ts: None,
320 full_size_preview_enabled: None,
321 icon_name: None,
322 reference_object_type: None,
323 product_name: None,
324 style: None,
325 }
326 }
327
328 pub fn text(mut self, text: impl Into<String>) -> Self {
329 self.text = Some(text.into());
330 self
331 }
332
333 pub fn app_id(mut self, app_id: impl Into<String>) -> Self {
334 self.app_id = Some(app_id.into());
335 self
336 }
337
338 pub fn entity_id(mut self, entity_id: impl Into<String>) -> Self {
339 self.entity_id = Some(entity_id.into());
340 self
341 }
342
343 pub fn icon_url(mut self, icon_url: impl Into<String>) -> Self {
344 self.icon_url = Some(icon_url.into());
345 self
346 }
347
348 pub fn channel_id(mut self, channel_id: impl Into<String>) -> Self {
349 self.channel_id = Some(channel_id.into());
350 self
351 }
352
353 pub fn ts(mut self, ts: impl Into<String>) -> Self {
354 self.ts = Some(ts.into());
355 self
356 }
357
358 pub fn full_size_preview_enabled(mut self, full_size_preview_enabled: bool) -> Self {
359 self.full_size_preview_enabled = Some(full_size_preview_enabled);
360 self
361 }
362
363 pub fn icon_name(mut self, icon_name: impl Into<String>) -> Self {
364 self.icon_name = Some(icon_name.into());
365 self
366 }
367
368 pub fn reference_object_type(mut self, reference_object_type: impl Into<String>) -> Self {
369 self.reference_object_type = Some(reference_object_type.into());
370 self
371 }
372
373 pub fn product_name(mut self, product_name: impl Into<String>) -> Self {
374 self.product_name = Some(product_name.into());
375 self
376 }
377
378 pub fn style(mut self, style: RichTextStyle) -> Self {
379 self.style = Some(style);
380 self
381 }
382}
383
384#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
386pub struct BroadcastElement {
387 r#type: Tag<Self>,
388 pub range: BroadcastRange,
389 #[serde(skip_serializing_if = "Option::is_none")]
390 pub style: Option<RichTextStyle>,
391}
392
393impl Tagged for BroadcastElement {
394 const TAG: &'static str = "broadcast";
395}
396
397impl BroadcastElement {
398 pub fn new(range: BroadcastRange) -> Self {
399 Self {
400 r#type: Tag::default(),
401 range,
402 style: None,
403 }
404 }
405
406 pub fn style(mut self, style: RichTextStyle) -> Self {
407 self.style = Some(style);
408 self
409 }
410}
411
412#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
414pub struct CanvasElement {
415 r#type: Tag<Self>,
416 pub file_id: String,
417 #[serde(skip_serializing_if = "Option::is_none")]
418 pub label: Option<String>,
419 #[serde(skip_serializing_if = "Option::is_none")]
420 pub hide_title: Option<bool>,
421 #[serde(skip_serializing_if = "Option::is_none")]
422 pub section_id: Option<String>,
423 #[serde(skip_serializing_if = "Option::is_none")]
424 pub style: Option<RichTextStyle>,
425 #[serde(skip_serializing_if = "Option::is_none")]
426 pub text: Option<String>,
427 #[serde(skip_serializing_if = "Option::is_none")]
428 pub url: Option<String>,
429 #[serde(skip_serializing_if = "Option::is_none")]
430 pub is_skill_invocation: Option<bool>,
431}
432
433impl Tagged for CanvasElement {
434 const TAG: &'static str = "canvas";
435}
436
437impl CanvasElement {
438 pub fn new(file_id: impl Into<String>) -> Self {
439 Self {
440 r#type: Tag::default(),
441 file_id: file_id.into(),
442 label: None,
443 hide_title: None,
444 section_id: None,
445 style: None,
446 text: None,
447 url: None,
448 is_skill_invocation: None,
449 }
450 }
451
452 pub fn label(mut self, label: impl Into<String>) -> Self {
453 self.label = Some(label.into());
454 self
455 }
456
457 pub fn hide_title(mut self, hide_title: bool) -> Self {
458 self.hide_title = Some(hide_title);
459 self
460 }
461
462 pub fn section_id(mut self, section_id: impl Into<String>) -> Self {
463 self.section_id = Some(section_id.into());
464 self
465 }
466
467 pub fn style(mut self, style: RichTextStyle) -> Self {
468 self.style = Some(style);
469 self
470 }
471
472 pub fn text(mut self, text: impl Into<String>) -> Self {
473 self.text = Some(text.into());
474 self
475 }
476
477 pub fn url(mut self, url: impl Into<String>) -> Self {
478 self.url = Some(url.into());
479 self
480 }
481
482 pub fn is_skill_invocation(mut self, is_skill_invocation: bool) -> Self {
483 self.is_skill_invocation = Some(is_skill_invocation);
484 self
485 }
486}
487
488#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
490pub struct CanvasUserMentionElement {
491 r#type: Tag<Self>,
492 pub user_id: String,
493 #[serde(skip_serializing_if = "Option::is_none")]
494 pub thread_id: Option<String>,
495 #[serde(skip_serializing_if = "Option::is_none")]
496 pub style: Option<RichTextStyle>,
497}
498
499impl Tagged for CanvasUserMentionElement {
500 const TAG: &'static str = "canvas_user_mention";
501}
502
503impl CanvasUserMentionElement {
504 pub fn new(user_id: impl Into<String>) -> Self {
505 Self {
506 r#type: Tag::default(),
507 user_id: user_id.into(),
508 thread_id: None,
509 style: None,
510 }
511 }
512
513 pub fn thread_id(mut self, thread_id: impl Into<String>) -> Self {
514 self.thread_id = Some(thread_id.into());
515 self
516 }
517
518 pub fn style(mut self, style: RichTextStyle) -> Self {
519 self.style = Some(style);
520 self
521 }
522}
523
524#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
526pub struct CanvasMessageUnfurlElement {
527 r#type: Tag<Self>,
528 pub root_message_ts: String,
529 pub root_message_channel: String,
530 #[serde(skip_serializing_if = "Option::is_none")]
531 pub style: Option<RichTextStyle>,
532}
533
534impl Tagged for CanvasMessageUnfurlElement {
535 const TAG: &'static str = "canvas_message_unfurl";
536}
537
538impl CanvasMessageUnfurlElement {
539 pub fn new(
540 root_message_ts: impl Into<String>,
541 root_message_channel: impl Into<String>,
542 ) -> Self {
543 Self {
544 r#type: Tag::default(),
545 root_message_ts: root_message_ts.into(),
546 root_message_channel: root_message_channel.into(),
547 style: None,
548 }
549 }
550
551 pub fn style(mut self, style: RichTextStyle) -> Self {
552 self.style = Some(style);
553 self
554 }
555}
556
557#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
559pub struct ChannelElement {
560 r#type: Tag<Self>,
561 pub channel_id: String,
562 #[serde(skip_serializing_if = "Option::is_none")]
563 pub tab_id: Option<String>,
564 #[serde(skip_serializing_if = "Option::is_none")]
565 pub style: Option<RichTextStyle>,
566 #[serde(skip_serializing_if = "Option::is_none")]
567 pub from_llm: Option<bool>,
568}
569
570impl Tagged for ChannelElement {
571 const TAG: &'static str = "channel";
572}
573
574impl ChannelElement {
575 pub fn new(channel_id: impl Into<String>) -> Self {
576 Self {
577 r#type: Tag::default(),
578 channel_id: channel_id.into(),
579 tab_id: None,
580 style: None,
581 from_llm: None,
582 }
583 }
584
585 pub fn tab_id(mut self, tab_id: impl Into<String>) -> Self {
586 self.tab_id = Some(tab_id.into());
587 self
588 }
589
590 pub fn style(mut self, style: RichTextStyle) -> Self {
591 self.style = Some(style);
592 self
593 }
594
595 pub fn from_llm(mut self, from_llm: bool) -> Self {
596 self.from_llm = Some(from_llm);
597 self
598 }
599}
600
601#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
603pub struct CitationElement {
604 r#type: Tag<Self>,
605 pub url: String,
606 pub text: String,
607 pub index: u32,
608 pub details: CitationDetails,
609 #[serde(skip_serializing_if = "Option::is_none")]
610 pub from_llm: Option<bool>,
611 #[serde(skip_serializing_if = "Option::is_none")]
612 pub is_slack_url: Option<bool>,
613}
614
615impl Tagged for CitationElement {
616 const TAG: &'static str = "citation";
617}
618
619impl CitationElement {
620 pub fn new(
621 url: impl Into<String>,
622 text: impl Into<String>,
623 index: u32,
624 details: impl Into<CitationDetails>,
625 ) -> Self {
626 Self {
627 r#type: Tag::default(),
628 url: url.into(),
629 text: text.into(),
630 index,
631 details: details.into(),
632 from_llm: None,
633 is_slack_url: None,
634 }
635 }
636
637 pub fn from_llm(mut self, from_llm: bool) -> Self {
638 self.from_llm = Some(from_llm);
639 self
640 }
641
642 pub fn is_slack_url(mut self, is_slack_url: bool) -> Self {
643 self.is_slack_url = Some(is_slack_url);
644 self
645 }
646}
647
648tagged_enum! {
649 pub enum CitationDetails("citation_type") {
651 File(FileCitation),
652 External(ExternalCitation),
653 Web(WebCitation),
654 Message(MessageCitation),
655 Memory(MemoryCitation),
656 }
657}
658
659#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
661pub struct FileCitation {
662 citation_type: Tag<Self>,
663 #[serde(skip_serializing_if = "Option::is_none")]
664 pub descriptor: Option<String>,
665 #[serde(skip_serializing_if = "Option::is_none")]
666 pub file_id: Option<String>,
667}
668
669impl Tagged for FileCitation {
670 const TAG: &'static str = "file";
671}
672
673impl FileCitation {
674 pub fn new() -> Self {
675 Self::default()
676 }
677
678 pub fn descriptor(mut self, descriptor: impl Into<String>) -> Self {
679 self.descriptor = Some(descriptor.into());
680 self
681 }
682
683 pub fn file_id(mut self, file_id: impl Into<String>) -> Self {
684 self.file_id = Some(file_id.into());
685 self
686 }
687}
688
689#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
691pub struct ExternalCitation {
692 citation_type: Tag<Self>,
693 #[serde(skip_serializing_if = "Option::is_none")]
694 pub app_name: Option<String>,
695 #[serde(skip_serializing_if = "Option::is_none")]
696 pub app_icon_url: Option<String>,
697}
698
699impl Tagged for ExternalCitation {
700 const TAG: &'static str = "external";
701}
702
703impl ExternalCitation {
704 pub fn new() -> Self {
705 Self::default()
706 }
707
708 pub fn app_name(mut self, app_name: impl Into<String>) -> Self {
709 self.app_name = Some(app_name.into());
710 self
711 }
712
713 pub fn app_icon_url(mut self, app_icon_url: impl Into<String>) -> Self {
714 self.app_icon_url = Some(app_icon_url.into());
715 self
716 }
717}
718
719#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
721pub struct WebCitation {
722 citation_type: Tag<Self>,
723 #[serde(skip_serializing_if = "Option::is_none")]
724 pub display_name: Option<String>,
725 #[serde(skip_serializing_if = "Option::is_none")]
726 pub title: Option<String>,
727 #[serde(skip_serializing_if = "Option::is_none")]
728 pub snippet: Option<String>,
729}
730
731impl Tagged for WebCitation {
732 const TAG: &'static str = "web";
733}
734
735impl WebCitation {
736 pub fn new() -> Self {
737 Self::default()
738 }
739
740 pub fn display_name(mut self, display_name: impl Into<String>) -> Self {
741 self.display_name = Some(display_name.into());
742 self
743 }
744
745 pub fn title(mut self, title: impl Into<String>) -> Self {
746 self.title = Some(title.into());
747 self
748 }
749
750 pub fn snippet(mut self, snippet: impl Into<String>) -> Self {
751 self.snippet = Some(snippet.into());
752 self
753 }
754}
755
756#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
758pub struct MessageCitation {
759 citation_type: Tag<Self>,
760 #[serde(skip_serializing_if = "Option::is_none")]
761 pub channel: Option<String>,
762 #[serde(skip_serializing_if = "Option::is_none")]
763 pub message_ts: Option<String>,
764}
765
766impl Tagged for MessageCitation {
767 const TAG: &'static str = "message";
768}
769
770impl MessageCitation {
771 pub fn new() -> Self {
772 Self::default()
773 }
774
775 pub fn channel(mut self, channel: impl Into<String>) -> Self {
776 self.channel = Some(channel.into());
777 self
778 }
779
780 pub fn message_ts(mut self, message_ts: impl Into<String>) -> Self {
781 self.message_ts = Some(message_ts.into());
782 self
783 }
784}
785
786#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
788pub struct MemoryCitation {
789 citation_type: Tag<Self>,
790 #[serde(skip_serializing_if = "Option::is_none")]
791 pub memory_id: Option<String>,
792}
793
794impl Tagged for MemoryCitation {
795 const TAG: &'static str = "memory";
796}
797
798impl MemoryCitation {
799 pub fn new() -> Self {
800 Self::default()
801 }
802
803 pub fn memory_id(mut self, memory_id: impl Into<String>) -> Self {
804 self.memory_id = Some(memory_id.into());
805 self
806 }
807}
808
809#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
811pub struct ColorElement {
812 r#type: Tag<Self>,
813 pub value: String,
814 #[serde(skip_serializing_if = "Option::is_none")]
815 pub style: Option<RichTextStyle>,
816}
817
818impl Tagged for ColorElement {
819 const TAG: &'static str = "color";
820}
821
822impl ColorElement {
823 pub fn new(value: impl Into<String>) -> Self {
824 Self {
825 r#type: Tag::default(),
826 value: value.into(),
827 style: None,
828 }
829 }
830
831 pub fn style(mut self, style: RichTextStyle) -> Self {
832 self.style = Some(style);
833 self
834 }
835}
836
837#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
839pub struct DateElement {
840 r#type: Tag<Self>,
841 pub timestamp: i64,
842 pub format: String,
843 #[serde(skip_serializing_if = "Option::is_none")]
844 pub timezone: Option<String>,
845 #[serde(skip_serializing_if = "Option::is_none")]
846 pub url: Option<String>,
847 #[serde(skip_serializing_if = "Option::is_none")]
848 pub fallback: Option<String>,
849 #[serde(skip_serializing_if = "Option::is_none")]
850 pub style: Option<RichTextStyle>,
851}
852
853impl Tagged for DateElement {
854 const TAG: &'static str = "date";
855}
856
857impl DateElement {
858 pub fn new(timestamp: i64, format: impl Into<String>) -> Self {
859 Self {
860 r#type: Tag::default(),
861 timestamp,
862 format: format.into(),
863 timezone: None,
864 url: None,
865 fallback: None,
866 style: None,
867 }
868 }
869
870 pub fn timezone(mut self, timezone: impl Into<String>) -> Self {
871 self.timezone = Some(timezone.into());
872 self
873 }
874
875 pub fn url(mut self, url: impl Into<String>) -> Self {
876 self.url = Some(url.into());
877 self
878 }
879
880 pub fn fallback(mut self, fallback: impl Into<String>) -> Self {
881 self.fallback = Some(fallback.into());
882 self
883 }
884
885 pub fn style(mut self, style: RichTextStyle) -> Self {
886 self.style = Some(style);
887 self
888 }
889}
890
891#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
893pub struct EmojiElement {
894 r#type: Tag<Self>,
895 pub name: String,
896 #[serde(skip_serializing_if = "Option::is_none")]
897 pub unicode: Option<String>,
898}
899
900impl Tagged for EmojiElement {
901 const TAG: &'static str = "emoji";
902}
903
904impl EmojiElement {
905 pub fn new(name: impl Into<String>) -> Self {
906 Self {
907 r#type: Tag::default(),
908 name: name.into(),
909 unicode: None,
910 }
911 }
912
913 pub fn unicode(mut self, unicode: impl Into<String>) -> Self {
914 self.unicode = Some(unicode.into());
915 self
916 }
917}
918
919#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
921pub struct FileElement {
922 r#type: Tag<Self>,
923 pub file_id: String,
924 #[serde(skip_serializing_if = "Option::is_none")]
925 pub style: Option<RichTextStyle>,
926 #[serde(skip_serializing_if = "Option::is_none")]
927 pub text: Option<String>,
928 #[serde(skip_serializing_if = "Option::is_none")]
929 pub url: Option<String>,
930 #[serde(skip_serializing_if = "Option::is_none")]
931 pub is_skill_invocation: Option<bool>,
932}
933
934impl Tagged for FileElement {
935 const TAG: &'static str = "file";
936}
937
938impl FileElement {
939 pub fn new(file_id: impl Into<String>) -> Self {
940 Self {
941 r#type: Tag::default(),
942 file_id: file_id.into(),
943 style: None,
944 text: None,
945 url: None,
946 is_skill_invocation: None,
947 }
948 }
949
950 pub fn style(mut self, style: RichTextStyle) -> Self {
951 self.style = Some(style);
952 self
953 }
954
955 pub fn text(mut self, text: impl Into<String>) -> Self {
956 self.text = Some(text.into());
957 self
958 }
959
960 pub fn url(mut self, url: impl Into<String>) -> Self {
961 self.url = Some(url.into());
962 self
963 }
964
965 pub fn is_skill_invocation(mut self, is_skill_invocation: bool) -> Self {
966 self.is_skill_invocation = Some(is_skill_invocation);
967 self
968 }
969}
970
971#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
973pub struct LinkElement {
974 r#type: Tag<Self>,
975 pub url: String,
976 #[serde(skip_serializing_if = "Option::is_none")]
977 pub text: Option<String>,
978 #[serde(skip_serializing_if = "Option::is_none")]
979 pub r#unsafe: Option<bool>,
980 #[serde(skip_serializing_if = "Option::is_none")]
981 pub from_llm: Option<bool>,
982 #[serde(skip_serializing_if = "Option::is_none")]
983 pub is_slack_url: Option<bool>,
984 #[serde(skip_serializing_if = "Option::is_none")]
985 pub truncated: Option<bool>,
986 #[serde(skip_serializing_if = "Option::is_none")]
987 pub style: Option<RichTextStyle>,
988}
989
990impl Tagged for LinkElement {
991 const TAG: &'static str = "link";
992}
993
994impl LinkElement {
995 pub fn new(url: impl Into<String>) -> Self {
996 Self {
997 r#type: Tag::default(),
998 url: url.into(),
999 text: None,
1000 r#unsafe: None,
1001 from_llm: None,
1002 is_slack_url: None,
1003 truncated: None,
1004 style: None,
1005 }
1006 }
1007
1008 pub fn text(mut self, text: impl Into<String>) -> Self {
1009 self.text = Some(text.into());
1010 self
1011 }
1012
1013 pub fn r#unsafe(mut self, r#unsafe: bool) -> Self {
1014 self.r#unsafe = Some(r#unsafe);
1015 self
1016 }
1017
1018 pub fn from_llm(mut self, from_llm: bool) -> Self {
1019 self.from_llm = Some(from_llm);
1020 self
1021 }
1022
1023 pub fn is_slack_url(mut self, is_slack_url: bool) -> Self {
1024 self.is_slack_url = Some(is_slack_url);
1025 self
1026 }
1027
1028 pub fn truncated(mut self, truncated: bool) -> Self {
1029 self.truncated = Some(truncated);
1030 self
1031 }
1032
1033 pub fn style(mut self, style: RichTextStyle) -> Self {
1034 self.style = Some(style);
1035 self
1036 }
1037}
1038
1039#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1041pub struct ListRecordElement {
1042 r#type: Tag<Self>,
1043 pub file_id: String,
1044 #[serde(skip_serializing_if = "Option::is_none")]
1045 pub record_id: Option<String>,
1046 #[serde(skip_serializing_if = "Option::is_none")]
1047 pub view_id: Option<String>,
1048 #[serde(skip_serializing_if = "Option::is_none")]
1049 pub style: Option<RichTextStyle>,
1050 #[serde(skip_serializing_if = "Option::is_none")]
1051 pub text: Option<String>,
1052 #[serde(skip_serializing_if = "Option::is_none")]
1053 pub url: Option<String>,
1054}
1055
1056impl Tagged for ListRecordElement {
1057 const TAG: &'static str = "list_record";
1058}
1059
1060impl ListRecordElement {
1061 pub fn new(file_id: impl Into<String>) -> Self {
1062 Self {
1063 r#type: Tag::default(),
1064 file_id: file_id.into(),
1065 record_id: None,
1066 view_id: None,
1067 style: None,
1068 text: None,
1069 url: None,
1070 }
1071 }
1072
1073 pub fn record_id(mut self, record_id: impl Into<String>) -> Self {
1074 self.record_id = Some(record_id.into());
1075 self
1076 }
1077
1078 pub fn view_id(mut self, view_id: impl Into<String>) -> Self {
1079 self.view_id = Some(view_id.into());
1080 self
1081 }
1082
1083 pub fn style(mut self, style: RichTextStyle) -> Self {
1084 self.style = Some(style);
1085 self
1086 }
1087
1088 pub fn text(mut self, text: impl Into<String>) -> Self {
1089 self.text = Some(text.into());
1090 self
1091 }
1092
1093 pub fn url(mut self, url: impl Into<String>) -> Self {
1094 self.url = Some(url.into());
1095 self
1096 }
1097}
1098
1099#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1101pub struct MessageMentionElement {
1102 r#type: Tag<Self>,
1103 pub channel_id: String,
1104 pub message_ts: String,
1105 #[serde(skip_serializing_if = "Option::is_none")]
1106 pub author_id: Option<String>,
1107 #[serde(skip_serializing_if = "Option::is_none")]
1108 pub thread_ts: Option<String>,
1109 #[serde(skip_serializing_if = "Option::is_none")]
1110 pub style: Option<RichTextStyle>,
1111 #[serde(skip_serializing_if = "Option::is_none")]
1112 pub text: Option<String>,
1113 #[serde(skip_serializing_if = "Option::is_none")]
1114 pub url: Option<String>,
1115}
1116
1117impl Tagged for MessageMentionElement {
1118 const TAG: &'static str = "message_mention";
1119}
1120
1121impl MessageMentionElement {
1122 pub fn new(channel_id: impl Into<String>, message_ts: impl Into<String>) -> Self {
1123 Self {
1124 r#type: Tag::default(),
1125 channel_id: channel_id.into(),
1126 message_ts: message_ts.into(),
1127 author_id: None,
1128 thread_ts: None,
1129 style: None,
1130 text: None,
1131 url: None,
1132 }
1133 }
1134
1135 pub fn author_id(mut self, author_id: impl Into<String>) -> Self {
1136 self.author_id = Some(author_id.into());
1137 self
1138 }
1139
1140 pub fn thread_ts(mut self, thread_ts: impl Into<String>) -> Self {
1141 self.thread_ts = Some(thread_ts.into());
1142 self
1143 }
1144
1145 pub fn style(mut self, style: RichTextStyle) -> Self {
1146 self.style = Some(style);
1147 self
1148 }
1149
1150 pub fn text(mut self, text: impl Into<String>) -> Self {
1151 self.text = Some(text.into());
1152 self
1153 }
1154
1155 pub fn url(mut self, url: impl Into<String>) -> Self {
1156 self.url = Some(url.into());
1157 self
1158 }
1159}
1160
1161#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1163pub struct SalesforceDataFieldElement {
1164 r#type: Tag<Self>,
1165 pub salesforce_record_id: String,
1166 #[serde(skip_serializing_if = "Option::is_none")]
1167 pub salesforce_field_label: Option<String>,
1168 #[serde(skip_serializing_if = "Option::is_none")]
1169 pub salesforce_field_api_name: Option<String>,
1170 #[serde(skip_serializing_if = "Option::is_none")]
1171 pub salesforce_include_field_label: Option<bool>,
1172 #[serde(skip_serializing_if = "Option::is_none")]
1173 pub style: Option<RichTextStyle>,
1174}
1175
1176impl Tagged for SalesforceDataFieldElement {
1177 const TAG: &'static str = "salesforce_data_field";
1178}
1179
1180impl SalesforceDataFieldElement {
1181 pub fn new(salesforce_record_id: impl Into<String>) -> Self {
1182 Self {
1183 r#type: Tag::default(),
1184 salesforce_record_id: salesforce_record_id.into(),
1185 salesforce_field_label: None,
1186 salesforce_field_api_name: None,
1187 salesforce_include_field_label: None,
1188 style: None,
1189 }
1190 }
1191
1192 pub fn salesforce_field_label(mut self, salesforce_field_label: impl Into<String>) -> Self {
1193 self.salesforce_field_label = Some(salesforce_field_label.into());
1194 self
1195 }
1196
1197 pub fn salesforce_field_api_name(
1198 mut self,
1199 salesforce_field_api_name: impl Into<String>,
1200 ) -> Self {
1201 self.salesforce_field_api_name = Some(salesforce_field_api_name.into());
1202 self
1203 }
1204
1205 pub fn salesforce_include_field_label(mut self, salesforce_include_field_label: bool) -> Self {
1206 self.salesforce_include_field_label = Some(salesforce_include_field_label);
1207 self
1208 }
1209
1210 pub fn style(mut self, style: RichTextStyle) -> Self {
1211 self.style = Some(style);
1212 self
1213 }
1214}
1215
1216#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1218pub struct TagElement {
1219 r#type: Tag<Self>,
1220 pub text: String,
1221 #[serde(skip_serializing_if = "Option::is_none")]
1222 pub color: Option<TagColor>,
1223 #[serde(skip_serializing_if = "Option::is_none")]
1224 pub style: Option<RichTextStyle>,
1225}
1226
1227impl Tagged for TagElement {
1228 const TAG: &'static str = "tag";
1229}
1230
1231impl TagElement {
1232 pub fn new(text: impl Into<String>) -> Self {
1233 Self {
1234 r#type: Tag::default(),
1235 text: text.into(),
1236 color: None,
1237 style: None,
1238 }
1239 }
1240
1241 pub fn color(mut self, color: TagColor) -> Self {
1242 self.color = Some(color);
1243 self
1244 }
1245
1246 pub fn style(mut self, style: RichTextStyle) -> Self {
1247 self.style = Some(style);
1248 self
1249 }
1250}
1251
1252#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1254pub struct TeamElement {
1255 r#type: Tag<Self>,
1256 pub team_id: String,
1257 #[serde(skip_serializing_if = "Option::is_none")]
1258 pub style: Option<RichTextStyle>,
1259}
1260
1261impl Tagged for TeamElement {
1262 const TAG: &'static str = "team";
1263}
1264
1265impl TeamElement {
1266 pub fn new(team_id: impl Into<String>) -> Self {
1267 Self {
1268 r#type: Tag::default(),
1269 team_id: team_id.into(),
1270 style: None,
1271 }
1272 }
1273
1274 pub fn style(mut self, style: RichTextStyle) -> Self {
1275 self.style = Some(style);
1276 self
1277 }
1278}
1279
1280#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1282pub struct TextElement {
1283 r#type: Tag<Self>,
1284 pub text: String,
1285 #[serde(skip_serializing_if = "Option::is_none")]
1286 pub style: Option<RichTextStyle>,
1287}
1288
1289impl Tagged for TextElement {
1290 const TAG: &'static str = "text";
1291}
1292
1293impl TextElement {
1294 pub fn new(text: impl Into<String>) -> Self {
1295 Self {
1296 r#type: Tag::default(),
1297 text: text.into(),
1298 style: None,
1299 }
1300 }
1301
1302 pub fn style(mut self, style: RichTextStyle) -> Self {
1303 self.style = Some(style);
1304 self
1305 }
1306}
1307
1308#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1310pub struct UserElement {
1311 r#type: Tag<Self>,
1312 pub user_id: String,
1313 #[serde(skip_serializing_if = "Option::is_none")]
1314 pub style: Option<RichTextStyle>,
1315 #[serde(skip_serializing_if = "Option::is_none")]
1316 pub from_llm: Option<bool>,
1317}
1318
1319impl Tagged for UserElement {
1320 const TAG: &'static str = "user";
1321}
1322
1323impl UserElement {
1324 pub fn new(user_id: impl Into<String>) -> Self {
1325 Self {
1326 r#type: Tag::default(),
1327 user_id: user_id.into(),
1328 style: None,
1329 from_llm: None,
1330 }
1331 }
1332
1333 pub fn style(mut self, style: RichTextStyle) -> Self {
1334 self.style = Some(style);
1335 self
1336 }
1337
1338 pub fn from_llm(mut self, from_llm: bool) -> Self {
1339 self.from_llm = Some(from_llm);
1340 self
1341 }
1342}
1343
1344#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1346pub struct UsergroupElement {
1347 r#type: Tag<Self>,
1348 pub usergroup_id: String,
1349 #[serde(skip_serializing_if = "Option::is_none")]
1350 pub style: Option<RichTextStyle>,
1351}
1352
1353impl Tagged for UsergroupElement {
1354 const TAG: &'static str = "usergroup";
1355}
1356
1357impl UsergroupElement {
1358 pub fn new(usergroup_id: impl Into<String>) -> Self {
1359 Self {
1360 r#type: Tag::default(),
1361 usergroup_id: usergroup_id.into(),
1362 style: None,
1363 }
1364 }
1365
1366 pub fn style(mut self, style: RichTextStyle) -> Self {
1367 self.style = Some(style);
1368 self
1369 }
1370}
1371
1372#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1374pub struct WorkObjectMentionElement {
1375 r#type: Tag<Self>,
1376 pub entity_id: String,
1377 pub app_id: String,
1378 pub text: String,
1379 pub url: String,
1380 #[serde(skip_serializing_if = "Option::is_none")]
1381 pub icon_url: Option<String>,
1382 #[serde(skip_serializing_if = "Option::is_none")]
1383 pub full_size_preview_enabled: Option<bool>,
1384 #[serde(skip_serializing_if = "Option::is_none")]
1385 pub product_name: Option<String>,
1386 #[serde(skip_serializing_if = "Option::is_none")]
1387 pub style: Option<RichTextStyle>,
1388}
1389
1390impl Tagged for WorkObjectMentionElement {
1391 const TAG: &'static str = "work_object_mention";
1392}
1393
1394impl WorkObjectMentionElement {
1395 pub fn new(
1396 entity_id: impl Into<String>,
1397 app_id: impl Into<String>,
1398 text: impl Into<String>,
1399 url: impl Into<String>,
1400 ) -> Self {
1401 Self {
1402 r#type: Tag::default(),
1403 entity_id: entity_id.into(),
1404 app_id: app_id.into(),
1405 text: text.into(),
1406 url: url.into(),
1407 icon_url: None,
1408 full_size_preview_enabled: None,
1409 product_name: None,
1410 style: None,
1411 }
1412 }
1413
1414 pub fn icon_url(mut self, icon_url: impl Into<String>) -> Self {
1415 self.icon_url = Some(icon_url.into());
1416 self
1417 }
1418
1419 pub fn full_size_preview_enabled(mut self, full_size_preview_enabled: bool) -> Self {
1420 self.full_size_preview_enabled = Some(full_size_preview_enabled);
1421 self
1422 }
1423
1424 pub fn product_name(mut self, product_name: impl Into<String>) -> Self {
1425 self.product_name = Some(product_name.into());
1426 self
1427 }
1428
1429 pub fn style(mut self, style: RichTextStyle) -> Self {
1430 self.style = Some(style);
1431 self
1432 }
1433}
1434
1435#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1437pub struct WorkflowMentionElement {
1438 r#type: Tag<Self>,
1439 pub workflow_id: String,
1440 pub function_trigger_id: String,
1441 pub text: String,
1442 #[serde(skip_serializing_if = "Option::is_none")]
1443 pub url: Option<String>,
1444 #[serde(skip_serializing_if = "Option::is_none")]
1445 pub channel_id: Option<String>,
1446 #[serde(skip_serializing_if = "Option::is_none")]
1447 pub ts: Option<String>,
1448 #[serde(skip_serializing_if = "Option::is_none")]
1449 pub style: Option<RichTextStyle>,
1450}
1451
1452impl Tagged for WorkflowMentionElement {
1453 const TAG: &'static str = "workflow_mention";
1454}
1455
1456impl WorkflowMentionElement {
1457 pub fn new(
1458 workflow_id: impl Into<String>,
1459 function_trigger_id: impl Into<String>,
1460 text: impl Into<String>,
1461 ) -> Self {
1462 Self {
1463 r#type: Tag::default(),
1464 workflow_id: workflow_id.into(),
1465 function_trigger_id: function_trigger_id.into(),
1466 text: text.into(),
1467 url: None,
1468 channel_id: None,
1469 ts: None,
1470 style: None,
1471 }
1472 }
1473
1474 pub fn url(mut self, url: impl Into<String>) -> Self {
1475 self.url = Some(url.into());
1476 self
1477 }
1478
1479 pub fn channel_id(mut self, channel_id: impl Into<String>) -> Self {
1480 self.channel_id = Some(channel_id.into());
1481 self
1482 }
1483
1484 pub fn ts(mut self, ts: impl Into<String>) -> Self {
1485 self.ts = Some(ts.into());
1486 self
1487 }
1488
1489 pub fn style(mut self, style: RichTextStyle) -> Self {
1490 self.style = Some(style);
1491 self
1492 }
1493}
1494
1495#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1497#[serde(rename_all = "snake_case")]
1498pub enum RichTextListStyle {
1499 Bullet,
1500 Ordered,
1501 #[serde(untagged)]
1502 Other(String),
1503}
1504
1505#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1507#[serde(rename_all = "snake_case")]
1508pub enum BroadcastRange {
1509 Here,
1510 Channel,
1511 Everyone,
1512 #[serde(untagged)]
1513 Other(String),
1514}
1515
1516#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
1518#[serde(rename_all = "snake_case")]
1519pub enum TagColor {
1520 Gray,
1521 Brown,
1522 Purple,
1523 Indigo,
1524 Blue,
1525 Green,
1526 Yellow,
1527 Orange,
1528 Red,
1529 #[serde(untagged)]
1530 Other(String),
1531}