notion_async_api/
block.rs

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/// Refer to:
15/// - [Notion JSON conventions](https://developers.notion.com/reference/intro#json-conventions)
16/// - [Block object](https://developers.notion.com/reference/block)
17#[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    // custom field, index in parent
26    #[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/// Refer to: [Block type](https://developers.notion.com/reference/block)
89#[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}