1use serde::{Deserialize, Serialize};
2
3use super::text::RichText;
4use crate::types::{Animation, Audio, Integer, Location, PhotoSize, Video, Voice};
5
6#[derive(Debug, Clone, Deserialize, Serialize)]
8#[serde(from = "RawRichBlock", into = "RawRichBlock")]
9pub enum RichBlock {
10 Anchor(String),
12 Animation(RichBlockAnimation),
14 Audio(RichBlockAudio),
16 BlockQuotation(RichBlockBlockQuotation),
18 Collage(RichBlockCollage),
20 Details(RichBlockDetails),
22 Divider,
24 Footer(RichText),
26 List(Vec<RichBlockListItem>),
28 Map(RichBlockMap),
30 MathematicalExpression(String),
32 Paragraph(RichText),
34 Photo(RichBlockPhoto),
36 Preformatted(RichBlockPreformatted),
38 PullQuotation(RichBlockPullQuotation),
40 SectionHeading(RichText, Integer),
42 Slideshow(RichBlockSlideshow),
44 Table(RichBlockTable),
46 Thinking(RichText),
50 Video(RichBlockVideo),
52 VoiceNote(RichBlockVoiceNote),
54}
55
56impl RichBlock {
57 pub fn anchor<T>(value: T) -> Self
63 where
64 T: Into<String>,
65 {
66 Self::Anchor(value.into())
67 }
68
69 pub fn animation<T>(value: T) -> Self
75 where
76 T: Into<RichBlockAnimation>,
77 {
78 Self::Animation(value.into())
79 }
80
81 pub fn audio<T>(value: T) -> Self
87 where
88 T: Into<RichBlockAudio>,
89 {
90 Self::Audio(value.into())
91 }
92
93 pub fn block_quotation<T>(value: T) -> Self
99 where
100 T: Into<RichBlockBlockQuotation>,
101 {
102 Self::BlockQuotation(value.into())
103 }
104
105 pub fn collage<T>(value: T) -> Self
111 where
112 T: Into<RichBlockCollage>,
113 {
114 Self::Collage(value.into())
115 }
116
117 pub fn details<T>(value: T) -> Self
123 where
124 T: Into<RichBlockDetails>,
125 {
126 Self::Details(value.into())
127 }
128
129 pub fn footer<T>(value: T) -> Self
135 where
136 T: Into<RichText>,
137 {
138 Self::Footer(value.into())
139 }
140
141 pub fn list<A, B>(value: A) -> Self
147 where
148 A: IntoIterator<Item = B>,
149 B: Into<RichBlockListItem>,
150 {
151 Self::List(value.into_iter().map(Into::into).collect())
152 }
153
154 pub fn map<T>(value: T) -> Self
160 where
161 T: Into<RichBlockMap>,
162 {
163 Self::Map(value.into())
164 }
165
166 pub fn mathematical_expression<T>(value: T) -> Self
172 where
173 T: Into<String>,
174 {
175 Self::MathematicalExpression(value.into())
176 }
177
178 pub fn paragraph<T>(value: T) -> Self
184 where
185 T: Into<RichText>,
186 {
187 Self::Paragraph(value.into())
188 }
189
190 pub fn photo<T>(value: T) -> Self
196 where
197 T: Into<RichBlockPhoto>,
198 {
199 Self::Photo(value.into())
200 }
201
202 pub fn preformatted<T>(value: T) -> Self
208 where
209 T: Into<RichBlockPreformatted>,
210 {
211 Self::Preformatted(value.into())
212 }
213
214 pub fn pull_quotation<T>(value: T) -> Self
220 where
221 T: Into<RichBlockPullQuotation>,
222 {
223 Self::PullQuotation(value.into())
224 }
225
226 pub fn section_heading<T>(text: T, size: Integer) -> Self
233 where
234 T: Into<RichText>,
235 {
236 Self::SectionHeading(text.into(), size)
237 }
238
239 pub fn slideshow<T>(value: T) -> Self
245 where
246 T: Into<RichBlockSlideshow>,
247 {
248 Self::Slideshow(value.into())
249 }
250
251 pub fn table<T>(value: T) -> Self
257 where
258 T: Into<RichBlockTable>,
259 {
260 Self::Table(value.into())
261 }
262
263 pub fn thinking<T>(value: T) -> Self
269 where
270 T: Into<RichText>,
271 {
272 Self::Thinking(value.into())
273 }
274
275 pub fn video<T>(value: T) -> Self
281 where
282 T: Into<RichBlockVideo>,
283 {
284 Self::Video(value.into())
285 }
286
287 pub fn voice_note<T>(value: T) -> Self
293 where
294 T: Into<RichBlockVoiceNote>,
295 {
296 Self::VoiceNote(value.into())
297 }
298}
299
300impl From<&str> for RichBlock {
301 fn from(value: &str) -> Self {
302 Self::paragraph(value)
303 }
304}
305
306impl From<String> for RichBlock {
307 fn from(value: String) -> Self {
308 Self::paragraph(value)
309 }
310}
311
312#[serde_with::skip_serializing_none]
314#[derive(Debug, Clone, Deserialize, Serialize)]
315pub struct RichBlockAnimation {
316 pub animation: Animation,
318 pub caption: Option<RichBlockCaption>,
320 pub has_spoiler: Option<bool>,
322}
323
324impl From<Animation> for RichBlockAnimation {
325 fn from(value: Animation) -> Self {
326 Self {
327 animation: value,
328 has_spoiler: None,
329 caption: None,
330 }
331 }
332}
333
334impl<T> From<(Animation, T)> for RichBlockAnimation
335where
336 T: Into<RichBlockCaption>,
337{
338 fn from((animation, caption): (Animation, T)) -> Self {
339 Self::from(animation).with_caption(caption)
340 }
341}
342
343impl<T> From<(Animation, T, bool)> for RichBlockAnimation
344where
345 T: Into<RichBlockCaption>,
346{
347 fn from((animation, caption, has_spoiler): (Animation, T, bool)) -> Self {
348 Self::from(animation)
349 .with_caption(caption)
350 .with_has_spoiler(has_spoiler)
351 }
352}
353
354impl RichBlockAnimation {
355 pub fn with_caption<T>(mut self, value: T) -> Self
361 where
362 T: Into<RichBlockCaption>,
363 {
364 self.caption = Some(value.into());
365 self
366 }
367
368 pub fn with_has_spoiler(mut self, value: bool) -> Self {
374 self.has_spoiler = Some(value);
375 self
376 }
377}
378
379#[serde_with::skip_serializing_none]
381#[derive(Debug, Clone, Deserialize, Serialize)]
382pub struct RichBlockAudio {
383 pub audio: Audio,
385 pub caption: Option<RichBlockCaption>,
387}
388
389impl From<Audio> for RichBlockAudio {
390 fn from(value: Audio) -> Self {
391 Self {
392 audio: value,
393 caption: None,
394 }
395 }
396}
397
398impl<T> From<(Audio, T)> for RichBlockAudio
399where
400 T: Into<RichBlockCaption>,
401{
402 fn from((audio, caption): (Audio, T)) -> Self {
403 Self::from(audio).with_caption(caption)
404 }
405}
406
407impl RichBlockAudio {
408 pub fn with_caption<T>(mut self, value: T) -> Self
414 where
415 T: Into<RichBlockCaption>,
416 {
417 self.caption = Some(value.into());
418 self
419 }
420}
421
422#[serde_with::skip_serializing_none]
424#[derive(Debug, Clone, Deserialize, Serialize)]
425pub struct RichBlockBlockQuotation {
426 pub blocks: Vec<RichBlock>,
428 pub credit: Option<RichText>,
430}
431
432impl From<RichBlock> for RichBlockBlockQuotation {
433 fn from(value: RichBlock) -> Self {
434 Self {
435 blocks: vec![value],
436 credit: None,
437 }
438 }
439}
440
441impl<T> From<(RichBlock, T)> for RichBlockBlockQuotation
442where
443 T: Into<RichText>,
444{
445 fn from((block, credit): (RichBlock, T)) -> Self {
446 Self {
447 blocks: vec![block],
448 credit: Some(credit.into()),
449 }
450 }
451}
452
453impl<I> FromIterator<I> for RichBlockBlockQuotation
454where
455 I: Into<RichBlock>,
456{
457 fn from_iter<T>(value: T) -> Self
458 where
459 T: IntoIterator<Item = I>,
460 {
461 Self {
462 blocks: value.into_iter().map(Into::into).collect(),
463 credit: None,
464 }
465 }
466}
467
468impl RichBlockBlockQuotation {
469 pub fn with_credit<T>(mut self, value: T) -> Self
475 where
476 T: Into<RichText>,
477 {
478 self.credit = Some(value.into());
479 self
480 }
481}
482
483#[serde_with::skip_serializing_none]
485#[derive(Debug, Clone, Deserialize, Serialize)]
486pub struct RichBlockCaption {
487 pub text: RichText,
489 pub credit: Option<RichText>,
491}
492
493impl<T> From<T> for RichBlockCaption
494where
495 T: Into<RichText>,
496{
497 fn from(value: T) -> Self {
498 Self {
499 text: value.into(),
500 credit: None,
501 }
502 }
503}
504
505impl<A, B> From<(A, B)> for RichBlockCaption
506where
507 A: Into<RichText>,
508 B: Into<RichText>,
509{
510 fn from((text, credit): (A, B)) -> Self {
511 Self::from(text).with_credit(credit)
512 }
513}
514
515impl RichBlockCaption {
516 pub fn with_credit<T>(mut self, value: T) -> Self
522 where
523 T: Into<RichText>,
524 {
525 self.credit = Some(value.into());
526 self
527 }
528}
529
530#[serde_with::skip_serializing_none]
532#[derive(Debug, Clone, Deserialize, Serialize)]
533pub struct RichBlockCollage {
534 pub blocks: Vec<RichBlock>,
536 pub caption: Option<RichBlockCaption>,
538}
539
540impl<A, B> From<A> for RichBlockCollage
541where
542 A: IntoIterator<Item = B>,
543 B: Into<RichBlock>,
544{
545 fn from(value: A) -> Self {
546 value.into_iter().collect()
547 }
548}
549
550impl<I> FromIterator<I> for RichBlockCollage
551where
552 I: Into<RichBlock>,
553{
554 fn from_iter<T>(value: T) -> Self
555 where
556 T: IntoIterator<Item = I>,
557 {
558 Self {
559 blocks: value.into_iter().map(Into::into).collect(),
560 caption: None,
561 }
562 }
563}
564
565impl RichBlockCollage {
566 pub fn with_caption<T>(mut self, value: T) -> Self
572 where
573 T: Into<RichBlockCaption>,
574 {
575 self.caption = Some(value.into());
576 self
577 }
578}
579
580#[serde_with::skip_serializing_none]
582#[derive(Debug, Clone, Deserialize, Serialize)]
583pub struct RichBlockDetails {
584 pub blocks: Vec<RichBlock>,
586 pub summary: RichText,
588 pub is_open: Option<bool>,
590}
591
592impl<A, B, C> From<(A, C)> for RichBlockDetails
593where
594 A: IntoIterator<Item = B>,
595 B: Into<RichBlock>,
596 C: Into<RichText>,
597{
598 fn from((blocks, summary): (A, C)) -> Self {
599 Self::new(blocks, summary)
600 }
601}
602
603impl<A, B, C> From<(A, C, bool)> for RichBlockDetails
604where
605 A: IntoIterator<Item = B>,
606 B: Into<RichBlock>,
607 C: Into<RichText>,
608{
609 fn from((blocks, summary, is_open): (A, C, bool)) -> Self {
610 Self::new(blocks, summary).with_is_open(is_open)
611 }
612}
613
614impl RichBlockDetails {
615 pub fn new<A, B, C>(blocks: A, summary: C) -> Self
622 where
623 A: IntoIterator<Item = B>,
624 B: Into<RichBlock>,
625 C: Into<RichText>,
626 {
627 Self {
628 blocks: blocks.into_iter().map(Into::into).collect(),
629 summary: summary.into(),
630 is_open: None,
631 }
632 }
633
634 pub fn with_is_open(mut self, value: bool) -> Self {
640 self.is_open = Some(value);
641 self
642 }
643}
644
645#[serde_with::skip_serializing_none]
647#[derive(Clone, Debug, Deserialize, Serialize)]
648pub struct RichBlockListItem {
649 pub blocks: Vec<RichBlock>,
651 pub label: String,
653 pub has_checkbox: Option<bool>,
655 pub is_checked: Option<bool>,
657 #[serde(rename = "type")]
659 pub item_type: Option<RichBlockListItemType>,
660 pub value: Option<Integer>,
662}
663
664impl<A, B, C> From<(A, B)> for RichBlockListItem
665where
666 A: Into<String>,
667 B: IntoIterator<Item = C>,
668 C: Into<RichBlock>,
669{
670 fn from((label, blocks): (A, B)) -> Self {
671 Self::new(label, blocks)
672 }
673}
674
675impl RichBlockListItem {
676 pub fn new<A, B, C>(label: A, blocks: B) -> Self
683 where
684 A: Into<String>,
685 B: IntoIterator<Item = C>,
686 C: Into<RichBlock>,
687 {
688 Self {
689 blocks: blocks.into_iter().map(Into::into).collect(),
690 label: label.into(),
691 has_checkbox: None,
692 is_checked: None,
693 item_type: None,
694 value: None,
695 }
696 }
697
698 pub fn with_has_checkbox(mut self, value: bool) -> Self {
704 self.has_checkbox = Some(value);
705 self
706 }
707
708 pub fn with_is_checked(mut self, value: bool) -> Self {
714 self.is_checked = Some(value);
715 self
716 }
717
718 pub fn with_item_type(mut self, value: RichBlockListItemType) -> Self {
724 self.item_type = Some(value);
725 self
726 }
727
728 pub fn with_value(mut self, value: Integer) -> Self {
734 self.value = Some(value);
735 self
736 }
737}
738
739#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
741pub enum RichBlockListItemType {
742 #[serde(rename = "1")]
744 Decimal,
745 #[serde(rename = "a")]
747 LowercaseLetters,
748 #[serde(rename = "i")]
750 LowercaseRoman,
751 #[serde(rename = "A")]
753 UppercaseLetters,
754 #[serde(rename = "I")]
756 UppercaseRoman,
757}
758
759#[serde_with::skip_serializing_none]
761#[derive(Debug, Clone, Deserialize, Serialize)]
762pub struct RichBlockMap {
763 pub location: Location,
765 pub height: Integer,
767 pub width: Integer,
769 pub zoom: Integer,
771 pub caption: Option<RichBlockCaption>,
773}
774
775impl From<Location> for RichBlockMap {
776 fn from(value: Location) -> Self {
777 Self {
778 location: value,
779 zoom: 13,
780 width: 200,
781 height: 200,
782 caption: None,
783 }
784 }
785}
786
787impl RichBlockMap {
788 pub fn with_caption<T>(mut self, value: T) -> Self
794 where
795 T: Into<RichBlockCaption>,
796 {
797 self.caption = Some(value.into());
798 self
799 }
800
801 pub fn with_height(mut self, value: Integer) -> Self {
807 self.height = value;
808 self
809 }
810
811 pub fn with_width(mut self, value: Integer) -> Self {
817 self.width = value;
818 self
819 }
820
821 pub fn with_zoom(mut self, value: Integer) -> Self {
827 self.zoom = value;
828 self
829 }
830}
831
832#[serde_with::skip_serializing_none]
834#[derive(Debug, Clone, Deserialize, Serialize)]
835pub struct RichBlockPhoto {
836 pub photo: Vec<PhotoSize>,
838 pub caption: Option<RichBlockCaption>,
840 pub has_spoiler: Option<bool>,
842}
843
844impl<T> From<T> for RichBlockPhoto
845where
846 T: IntoIterator<Item = PhotoSize>,
847{
848 fn from(value: T) -> Self {
849 Self::from_iter(value)
850 }
851}
852
853impl FromIterator<PhotoSize> for RichBlockPhoto {
854 fn from_iter<T>(value: T) -> Self
855 where
856 T: IntoIterator<Item = PhotoSize>,
857 {
858 Self {
859 photo: value.into_iter().collect(),
860 caption: None,
861 has_spoiler: None,
862 }
863 }
864}
865
866impl RichBlockPhoto {
867 pub fn with_caption<T>(mut self, value: T) -> Self
873 where
874 T: Into<RichBlockCaption>,
875 {
876 self.caption = Some(value.into());
877 self
878 }
879
880 pub fn with_has_spoiler(mut self, value: bool) -> Self {
886 self.has_spoiler = Some(value);
887 self
888 }
889}
890
891#[serde_with::skip_serializing_none]
893#[derive(Debug, Clone, Deserialize, Serialize)]
894pub struct RichBlockPreformatted {
895 pub text: RichText,
897 pub language: Option<String>,
899}
900
901impl<T> From<T> for RichBlockPreformatted
902where
903 T: Into<RichText>,
904{
905 fn from(value: T) -> Self {
906 Self {
907 text: value.into(),
908 language: None,
909 }
910 }
911}
912
913impl<A, B> From<(A, B)> for RichBlockPreformatted
914where
915 A: Into<String>,
916 B: Into<RichText>,
917{
918 fn from((language, text): (A, B)) -> Self {
919 Self {
920 text: text.into(),
921 language: Some(language.into()),
922 }
923 }
924}
925
926#[serde_with::skip_serializing_none]
928#[derive(Debug, Clone, Deserialize, Serialize)]
929pub struct RichBlockPullQuotation {
930 pub text: RichText,
932 pub credit: Option<RichText>,
934}
935
936impl<T> From<T> for RichBlockPullQuotation
937where
938 T: Into<RichText>,
939{
940 fn from(value: T) -> Self {
941 Self {
942 text: value.into(),
943 credit: None,
944 }
945 }
946}
947
948impl<A, B> From<(A, B)> for RichBlockPullQuotation
949where
950 A: Into<RichText>,
951 B: Into<RichText>,
952{
953 fn from((text, credit): (A, B)) -> Self {
954 Self {
955 text: text.into(),
956 credit: Some(credit.into()),
957 }
958 }
959}
960
961#[serde_with::skip_serializing_none]
963#[derive(Debug, Clone, Deserialize, Serialize)]
964pub struct RichBlockSlideshow {
965 pub blocks: Vec<RichBlock>,
967 pub caption: Option<RichBlockCaption>,
969}
970
971impl<A, B> From<A> for RichBlockSlideshow
972where
973 A: IntoIterator<Item = B>,
974 B: Into<RichBlock>,
975{
976 fn from(value: A) -> Self {
977 value.into_iter().collect()
978 }
979}
980
981impl<I> FromIterator<I> for RichBlockSlideshow
982where
983 I: Into<RichBlock>,
984{
985 fn from_iter<T>(value: T) -> Self
986 where
987 T: IntoIterator<Item = I>,
988 {
989 Self {
990 blocks: value.into_iter().map(Into::into).collect(),
991 caption: None,
992 }
993 }
994}
995
996impl RichBlockSlideshow {
997 pub fn with_caption<T>(mut self, value: T) -> Self
1003 where
1004 T: Into<RichBlockCaption>,
1005 {
1006 self.caption = Some(value.into());
1007 self
1008 }
1009}
1010
1011#[serde_with::skip_serializing_none]
1013#[derive(Debug, Clone, Deserialize, Serialize)]
1014pub struct RichBlockTable {
1015 pub cells: Vec<Vec<RichBlockTableCell>>,
1017 pub caption: Option<RichText>,
1019 pub is_bordered: Option<bool>,
1021 pub is_striped: Option<bool>,
1023}
1024
1025impl<A, B, C> From<A> for RichBlockTable
1026where
1027 A: IntoIterator<Item = B>,
1028 B: IntoIterator<Item = C>,
1029 C: Into<RichBlockTableCell>,
1030{
1031 fn from(value: A) -> Self {
1032 value.into_iter().collect()
1033 }
1034}
1035
1036impl<A, B> FromIterator<A> for RichBlockTable
1037where
1038 A: IntoIterator<Item = B>,
1039 B: Into<RichBlockTableCell>,
1040{
1041 fn from_iter<T>(value: T) -> Self
1042 where
1043 T: IntoIterator<Item = A>,
1044 {
1045 Self {
1046 cells: value
1047 .into_iter()
1048 .map(|x| x.into_iter().map(Into::into).collect())
1049 .collect(),
1050 caption: None,
1051 is_bordered: None,
1052 is_striped: None,
1053 }
1054 }
1055}
1056
1057impl RichBlockTable {
1058 pub fn with_caption<T>(mut self, value: T) -> Self
1064 where
1065 T: Into<RichText>,
1066 {
1067 self.caption = Some(value.into());
1068 self
1069 }
1070
1071 pub fn with_is_bordered(mut self, value: bool) -> Self {
1077 self.is_bordered = Some(value);
1078 self
1079 }
1080
1081 pub fn with_is_striped(mut self, value: bool) -> Self {
1087 self.is_striped = Some(value);
1088 self
1089 }
1090}
1091
1092#[serde_with::skip_serializing_none]
1094#[derive(Debug, Default, Clone, Deserialize, Serialize)]
1095pub struct RichBlockTableCell {
1096 pub align: RichBlockTableCellAlign,
1098 pub valign: RichBlockTableCellValign,
1100 pub colspan: Option<Integer>,
1102 pub is_header: Option<bool>,
1104 pub rowspan: Option<Integer>,
1106 pub text: Option<RichText>,
1110}
1111
1112impl<T> From<T> for RichBlockTableCell
1113where
1114 T: Into<RichText>,
1115{
1116 fn from(value: T) -> Self {
1117 Self::default().with_text(value)
1118 }
1119}
1120
1121impl RichBlockTableCell {
1122 pub fn with_align(mut self, value: RichBlockTableCellAlign) -> Self {
1128 self.align = value;
1129 self
1130 }
1131
1132 pub fn with_colspan(mut self, value: Integer) -> Self {
1138 self.colspan = Some(value);
1139 self
1140 }
1141
1142 pub fn with_is_header(mut self, value: bool) -> Self {
1148 self.is_header = Some(value);
1149 self
1150 }
1151
1152 pub fn with_rowspan(mut self, value: Integer) -> Self {
1158 self.rowspan = Some(value);
1159 self
1160 }
1161
1162 pub fn with_text<T>(mut self, value: T) -> Self
1168 where
1169 T: Into<RichText>,
1170 {
1171 self.text = Some(value.into());
1172 self
1173 }
1174
1175 pub fn with_valign(mut self, value: RichBlockTableCellValign) -> Self {
1181 self.valign = value;
1182 self
1183 }
1184}
1185
1186#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize)]
1188#[serde(rename_all = "snake_case")]
1189pub enum RichBlockTableCellAlign {
1190 #[default]
1192 Left,
1193 Center,
1195 Right,
1197}
1198
1199#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize)]
1201#[serde(rename_all = "snake_case")]
1202pub enum RichBlockTableCellValign {
1203 Top,
1205 #[default]
1207 Middle,
1208 Bottom,
1210}
1211
1212#[serde_with::skip_serializing_none]
1214#[derive(Debug, Clone, Deserialize, Serialize)]
1215pub struct RichBlockVideo {
1216 pub video: Video,
1218 pub caption: Option<RichBlockCaption>,
1220 pub has_spoiler: Option<bool>,
1222}
1223
1224impl From<Video> for RichBlockVideo {
1225 fn from(value: Video) -> Self {
1226 Self {
1227 video: value,
1228 caption: None,
1229 has_spoiler: None,
1230 }
1231 }
1232}
1233
1234impl<T> From<(Video, T)> for RichBlockVideo
1235where
1236 T: Into<RichBlockCaption>,
1237{
1238 fn from((video, caption): (Video, T)) -> Self {
1239 Self {
1240 video,
1241 caption: Some(caption.into()),
1242 has_spoiler: None,
1243 }
1244 }
1245}
1246
1247impl<T> From<(Video, T, bool)> for RichBlockVideo
1248where
1249 T: Into<RichBlockCaption>,
1250{
1251 fn from((video, caption, has_spoiler): (Video, T, bool)) -> Self {
1252 Self {
1253 video,
1254 caption: Some(caption.into()),
1255 has_spoiler: Some(has_spoiler),
1256 }
1257 }
1258}
1259
1260#[serde_with::skip_serializing_none]
1262#[derive(Debug, Clone, Deserialize, Serialize)]
1263pub struct RichBlockVoiceNote {
1264 pub voice_note: Voice,
1266 pub caption: Option<RichBlockCaption>,
1268}
1269
1270impl From<Voice> for RichBlockVoiceNote {
1271 fn from(value: Voice) -> Self {
1272 Self {
1273 voice_note: value,
1274 caption: None,
1275 }
1276 }
1277}
1278
1279impl<T> From<(Voice, T)> for RichBlockVoiceNote
1280where
1281 T: Into<RichBlockCaption>,
1282{
1283 fn from((voice_note, caption): (Voice, T)) -> Self {
1284 Self {
1285 voice_note,
1286 caption: Some(caption.into()),
1287 }
1288 }
1289}
1290
1291#[serde_with::skip_serializing_none]
1292#[derive(Debug, Clone, Deserialize, Serialize)]
1293#[serde(rename_all = "snake_case", tag = "type")]
1294enum RawRichBlock {
1295 Anchor { name: String },
1296 Animation(RichBlockAnimation),
1297 Audio(RichBlockAudio),
1298 BlockQuotation(RichBlockBlockQuotation),
1299 Collage(RichBlockCollage),
1300 Details(RichBlockDetails),
1301 Divider,
1302 Footer { text: RichText },
1303 List { items: Vec<RichBlockListItem> },
1304 Map(RichBlockMap),
1305 MathematicalExpression { expression: String },
1306 Paragraph { text: RichText },
1307 Photo(RichBlockPhoto),
1308 Preformatted(RichBlockPreformatted),
1309 PullQuotation(RichBlockPullQuotation),
1310 SectionHeading { text: RichText, size: Integer },
1311 Slideshow(RichBlockSlideshow),
1312 Table(RichBlockTable),
1313 Thinking { text: RichText },
1314 Video(RichBlockVideo),
1315 VoiceNote(RichBlockVoiceNote),
1316}
1317
1318impl From<RichBlock> for RawRichBlock {
1319 fn from(value: RichBlock) -> Self {
1320 match value {
1321 RichBlock::Anchor(name) => Self::Anchor { name },
1322 RichBlock::Animation(value) => Self::Animation(value),
1323 RichBlock::Audio(value) => Self::Audio(value),
1324 RichBlock::BlockQuotation(value) => Self::BlockQuotation(value),
1325 RichBlock::Collage(value) => Self::Collage(value),
1326 RichBlock::Details(value) => Self::Details(value),
1327 RichBlock::Divider => Self::Divider,
1328 RichBlock::Footer(text) => Self::Footer { text },
1329 RichBlock::List(items) => Self::List { items },
1330 RichBlock::Map(value) => Self::Map(value),
1331 RichBlock::MathematicalExpression(expression) => Self::MathematicalExpression { expression },
1332 RichBlock::Paragraph(text) => Self::Paragraph { text },
1333 RichBlock::Photo(value) => Self::Photo(value),
1334 RichBlock::Preformatted(value) => Self::Preformatted(value),
1335 RichBlock::PullQuotation(value) => Self::PullQuotation(value),
1336 RichBlock::SectionHeading(text, size) => Self::SectionHeading { text, size },
1337 RichBlock::Slideshow(value) => Self::Slideshow(value),
1338 RichBlock::Table(value) => Self::Table(value),
1339 RichBlock::Thinking(text) => Self::Thinking { text },
1340 RichBlock::Video(value) => Self::Video(value),
1341 RichBlock::VoiceNote(value) => Self::VoiceNote(value),
1342 }
1343 }
1344}
1345
1346impl From<RawRichBlock> for RichBlock {
1347 fn from(value: RawRichBlock) -> Self {
1348 match value {
1349 RawRichBlock::Anchor { name } => Self::Anchor(name),
1350 RawRichBlock::Animation(value) => Self::Animation(value),
1351 RawRichBlock::Audio(value) => Self::Audio(value),
1352 RawRichBlock::BlockQuotation(value) => Self::BlockQuotation(value),
1353 RawRichBlock::Collage(value) => Self::Collage(value),
1354 RawRichBlock::Details(value) => Self::Details(value),
1355 RawRichBlock::Divider => Self::Divider,
1356 RawRichBlock::Footer { text } => Self::Footer(text),
1357 RawRichBlock::List { items } => Self::List(items),
1358 RawRichBlock::Map(value) => Self::Map(value),
1359 RawRichBlock::MathematicalExpression { expression } => Self::MathematicalExpression(expression),
1360 RawRichBlock::Paragraph { text } => Self::Paragraph(text),
1361 RawRichBlock::Photo(value) => Self::Photo(value),
1362 RawRichBlock::Preformatted(value) => Self::Preformatted(value),
1363 RawRichBlock::PullQuotation(value) => Self::PullQuotation(value),
1364 RawRichBlock::SectionHeading { text, size } => Self::SectionHeading(text, size),
1365 RawRichBlock::Slideshow(value) => Self::Slideshow(value),
1366 RawRichBlock::Table(value) => Self::Table(value),
1367 RawRichBlock::Thinking { text } => Self::Thinking(text),
1368 RawRichBlock::Video(value) => Self::Video(value),
1369 RawRichBlock::VoiceNote(value) => Self::VoiceNote(value),
1370 }
1371 }
1372}