1use std::collections::BTreeMap;
2use std::fmt::Display;
3
4use monostate::MustBe;
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7use serde_with::serde_as;
8
9use crate::{
10 misc::Unquotes,
11 object::{Object, ObjectCommon},
12};
13
14#[serde_as]
18#[derive(Serialize, Deserialize, Debug, Clone)]
19pub struct Block {
20 object: MustBe!("block"),
21
22 #[serde(flatten)]
23 pub obj: ObjectCommon,
24
25 #[serde(default)]
27 pub child_index: usize,
28
29 pub has_children: bool,
30
31 #[serde(rename = "type")]
32 pub block_type: BlockType,
33
34 #[serde(flatten)]
35 pub type_data: BlockTypeData,
36}
37
38#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
39#[serde(rename_all = "snake_case")]
40pub enum BlockType {
41 ChildPage,
42 ChildDatabase,
43 Bookmark,
44 Breadcrumb,
45 BulletedListItem,
46 Callout,
47 Code,
48 Column,
49 ColumnList,
50 Divider,
51 Embed,
52 Equation,
53 File,
54
55 #[serde(rename = "heading_1")]
56 Heading1,
57 #[serde(rename = "heading_2")]
58 Heading2,
59 #[serde(rename = "heading_3")]
60 Heading3,
61
62 Image,
63 LinkPreview,
64 LinkToPreview,
65 Mention,
66 NumberedListItem,
67 Paragraph,
68 Pdf,
69 Quote,
70 SyncedBlock,
71 Table,
72 TableRow,
73 TableOfContents,
74 Template,
75 ToDo,
76 Toggle,
77 Video,
78 Unsupported,
79}
80
81impl Display for BlockType {
82 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83 let s = serde_json::to_string(self).unwrap_or("".to_owned());
84 s.unquotes().fmt(f)
85 }
86}
87
88#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
90#[serde(rename_all = "snake_case")]
91pub enum BlockTypeData {
92 ChildPage {
93 title: String,
94 },
95 ChildDatabase {
96 title: String,
97 },
98 Bookmark(BTreeMap<String, Value>),
99 Breadcrumb(BTreeMap<String, Value>),
100 BulletedListItem(BTreeMap<String, Value>),
101 Callout(BTreeMap<String, Value>),
102 Code(BTreeMap<String, Value>),
103 Column(BTreeMap<String, Value>),
104 ColumnList(BTreeMap<String, Value>),
105 Divider(BTreeMap<String, Value>),
106 Embed(BTreeMap<String, Value>),
107 Equation(BTreeMap<String, Value>),
108 File(BTreeMap<String, Value>),
109
110 #[serde(rename = "heading_1")]
111 Heading1(BTreeMap<String, Value>),
112 #[serde(rename = "heading_2")]
113 Heading2(BTreeMap<String, Value>),
114 #[serde(rename = "heading_3")]
115 Heading3(BTreeMap<String, Value>),
116
117 Image(BTreeMap<String, Value>),
118 LinkPreview(BTreeMap<String, Value>),
119 LinkToPreview(BTreeMap<String, Value>),
120 Mention(BTreeMap<String, Value>),
121 NumberedListItem(BTreeMap<String, Value>),
122 Paragraph(BTreeMap<String, Value>),
123 Pdf(BTreeMap<String, Value>),
124 Quote(BTreeMap<String, Value>),
125 SyncedBlock(BTreeMap<String, Value>),
126 Table(BTreeMap<String, Value>),
127 TableRow(BTreeMap<String, Value>),
128 TableOfContents(BTreeMap<String, Value>),
129 Template(BTreeMap<String, Value>),
130 ToDo(BTreeMap<String, Value>),
131 Toggle(BTreeMap<String, Value>),
132 Video(BTreeMap<String, Value>),
133 Unsupported(BTreeMap<String, Value>),
134}
135
136impl Object for Block {
137 fn id(&self) -> &str {
138 &self.obj.id
139 }
140
141 fn object_type(&self) -> crate::object::ObjectType {
142 crate::object::ObjectType::Block
143 }
144}