notion_api_client/models/
block.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4use crate::ids::{AsIdentifier, BlockId, DatabaseId, PageId};
5use crate::models::text::{RichText, TextColor};
6use crate::models::users::UserCommon;
7
8mod tests;
9
10#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
11pub struct BlockCommon {
12    pub id: BlockId,
13    pub created_time: DateTime<Utc>,
14    pub last_edited_time: DateTime<Utc>,
15    pub has_children: bool,
16    pub created_by: UserCommon,
17    pub last_edited_by: UserCommon,
18}
19
20#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
21pub struct TextAndChildren {
22    pub rich_text: Vec<RichText>,
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub children: Option<Vec<Block>>,
25    pub color: TextColor,
26}
27
28#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
29pub struct Text {
30    pub rich_text: Vec<RichText>,
31}
32
33#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
34pub struct InternalFileObject {
35    url: String,
36    expiry_time: DateTime<Utc>,
37}
38
39#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
40pub struct ExternalFileObject {
41    url: String,
42}
43
44#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
45#[serde(tag = "type")]
46#[serde(rename_all = "snake_case")]
47pub enum FileOrEmojiObject {
48    Emoji { emoji: String },
49    File { file: InternalFileObject },
50    External { external: ExternalFileObject },
51}
52
53#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
54#[serde(tag = "type")]
55#[serde(rename_all = "snake_case")]
56pub enum FileObject {
57    File { file: InternalFileObject },
58    External { external: ExternalFileObject },
59}
60
61#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
62pub struct Callout {
63    pub rich_text: Vec<RichText>,
64    pub icon: FileOrEmojiObject,
65    pub color: TextColor,
66}
67
68#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
69pub struct ToDoFields {
70    pub rich_text: Vec<RichText>,
71    pub checked: bool,
72    #[serde(skip_serializing_if = "Option::is_none")]
73    pub children: Option<Vec<Block>>,
74    pub color: TextColor,
75}
76
77#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
78pub struct ChildPageFields {
79    pub title: String,
80}
81
82#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
83pub struct ChildDatabaseFields {
84    pub title: String,
85}
86
87#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
88pub struct EmbedFields {
89    pub url: String,
90}
91
92#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
93pub struct BookmarkFields {
94    pub url: String,
95    pub caption: Vec<RichText>,
96}
97
98#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
99#[serde(rename_all = "lowercase")]
100pub enum CodeLanguage {
101    Abap,
102    Arduino,
103    Bash,
104    Basic,
105    C,
106    Clojure,
107    Coffeescript,
108    #[serde(rename = "c++")]
109    CPlusPlus,
110    #[serde(rename = "c#")]
111    CSharp,
112    Css,
113    Dart,
114    Diff,
115    Docker,
116    Elixir,
117    Elm,
118    Erlang,
119    Flow,
120    Fortran,
121    #[serde(rename = "f#")]
122    FSharp,
123    Gherkin,
124    Glsl,
125    Go,
126    Graphql,
127    Groovy,
128    Haskell,
129    Html,
130    Java,
131    Javascript,
132    Json,
133    Julia,
134    Kotlin,
135    Latex,
136    Less,
137    Lisp,
138    Livescript,
139    Lua,
140    Makefile,
141    Markdown,
142    Markup,
143    Matlab,
144    Mermaid,
145    Nix,
146    #[serde(rename = "objective-c")]
147    ObjectiveC,
148    Ocaml,
149    Pascal,
150    Perl,
151    Php,
152    #[serde(rename = "plain text")]
153    PlainText,
154    Powershell,
155    Prolog,
156    Protobuf,
157    Python,
158    R,
159    Reason,
160    Ruby,
161    Rust,
162    Sass,
163    Scala,
164    Scheme,
165    Scss,
166    Shell,
167    Sql,
168    Swift,
169    Typescript,
170    #[serde(rename = "vb.net")]
171    VbNet,
172    Verilog,
173    Vhdl,
174    #[serde(rename = "visual basic")]
175    VisualBasic,
176    Webassembly,
177    Xml,
178    Yaml,
179    #[serde(rename = "java/c/c++/c#")]
180    JavaCAndCPlusPlusAndCSharp,
181}
182
183#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
184pub struct CodeFields {
185    pub rich_text: Vec<RichText>,
186    pub caption: Vec<RichText>,
187    pub language: CodeLanguage,
188}
189
190#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
191pub struct Equation {
192    pub expression: String,
193}
194
195#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
196pub struct TableOfContents {
197    pub color: TextColor,
198}
199
200#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
201pub struct ColumnListFields {
202    pub children: Vec<Block>,
203}
204
205#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
206pub struct ColumnFields {
207    pub children: Vec<Block>,
208}
209
210#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
211pub struct LinkPreviewFields {
212    pub url: String,
213}
214
215#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
216pub struct TemplateFields {
217    pub rich_text: Vec<RichText>,
218    pub children: Vec<Block>,
219}
220
221#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
222#[serde(tag = "type")]
223#[serde(rename_all = "snake_case")]
224pub enum LinkToPageFields {
225    PageId { page_id: PageId },
226    DatabaseId { database_id: DatabaseId },
227}
228
229#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
230pub struct SyncedFromObject {
231    pub block_id: BlockId,
232}
233
234#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
235pub struct SyncedBlockFields {
236    pub synced_from: Option<SyncedFromObject>,
237    pub children: Vec<Block>,
238}
239
240#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
241pub struct TableFields {
242    pub table_width: u64,
243    pub has_column_header: bool,
244    pub has_row_header: bool,
245    pub children: Vec<Block>,
246}
247
248#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
249pub struct TableRowFields {
250    pub cells: Vec<RichText>,
251}
252
253#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
254#[serde(tag = "type")]
255#[serde(rename_all = "snake_case")]
256pub enum Block {
257    Paragraph {
258        #[serde(flatten)]
259        common: BlockCommon,
260        paragraph: TextAndChildren,
261    },
262    #[serde(rename = "heading_1")]
263    Heading1 {
264        #[serde(flatten)]
265        common: BlockCommon,
266        heading_1: Text,
267    },
268    #[serde(rename = "heading_2")]
269    Heading2 {
270        #[serde(flatten)]
271        common: BlockCommon,
272        heading_2: Text,
273    },
274    #[serde(rename = "heading_3")]
275    Heading3 {
276        #[serde(flatten)]
277        common: BlockCommon,
278        heading_3: Text,
279    },
280    Callout {
281        #[serde(flatten)]
282        common: BlockCommon,
283        callout: Callout,
284    },
285    Quote {
286        #[serde(flatten)]
287        common: BlockCommon,
288        quote: TextAndChildren,
289    },
290    BulletedListItem {
291        #[serde(flatten)]
292        common: BlockCommon,
293        bulleted_list_item: TextAndChildren,
294    },
295    NumberedListItem {
296        #[serde(flatten)]
297        common: BlockCommon,
298        numbered_list_item: TextAndChildren,
299    },
300    ToDo {
301        #[serde(flatten)]
302        common: BlockCommon,
303        to_do: ToDoFields,
304    },
305    Toggle {
306        #[serde(flatten)]
307        common: BlockCommon,
308        toggle: TextAndChildren,
309    },
310    Code {
311        #[serde(flatten)]
312        common: BlockCommon,
313        code: CodeFields,
314    },
315    ChildPage {
316        #[serde(flatten)]
317        common: BlockCommon,
318        child_page: ChildPageFields,
319    },
320    ChildDatabase {
321        #[serde(flatten)]
322        common: BlockCommon,
323        child_page: ChildDatabaseFields,
324    },
325    Embed {
326        #[serde(flatten)]
327        common: BlockCommon,
328        embed: EmbedFields,
329    },
330    Image {
331        #[serde(flatten)]
332        common: BlockCommon,
333        image: FileObject,
334    },
335    Video {
336        #[serde(flatten)]
337        common: BlockCommon,
338        video: FileObject,
339    },
340    File {
341        #[serde(flatten)]
342        common: BlockCommon,
343        file: FileObject,
344        caption: Text,
345    },
346    Pdf {
347        #[serde(flatten)]
348        common: BlockCommon,
349        pdf: FileObject,
350    },
351    Bookmark {
352        #[serde(flatten)]
353        common: BlockCommon,
354        bookmark: BookmarkFields,
355    },
356    Equation {
357        #[serde(flatten)]
358        common: BlockCommon,
359        equation: Equation,
360    },
361    Divider {
362        #[serde(flatten)]
363        common: BlockCommon,
364    },
365    TableOfContents {
366        #[serde(flatten)]
367        common: BlockCommon,
368        table_of_contents: TableOfContents,
369    },
370    Breadcrumb {
371        #[serde(flatten)]
372        common: BlockCommon,
373    },
374    ColumnList {
375        #[serde(flatten)]
376        common: BlockCommon,
377        column_list: ColumnListFields,
378    },
379    Column {
380        #[serde(flatten)]
381        common: BlockCommon,
382        column: ColumnFields,
383    },
384    LinkPreview {
385        #[serde(flatten)]
386        common: BlockCommon,
387        link_preview: LinkPreviewFields,
388    },
389    Template {
390        #[serde(flatten)]
391        common: BlockCommon,
392        template: TemplateFields,
393    },
394    LinkToPage {
395        #[serde(flatten)]
396        common: BlockCommon,
397        link_to_page: LinkToPageFields,
398    },
399    Table {
400        #[serde(flatten)]
401        common: BlockCommon,
402        table: TableFields,
403    },
404    SyncedBlock {
405        #[serde(flatten)]
406        common: BlockCommon,
407        synced_block: SyncedBlockFields,
408    },
409    TableRow {
410        #[serde(flatten)]
411        common: BlockCommon,
412        table_row: TableRowFields,
413    },
414    Unsupported {
415        #[serde(flatten)]
416        common: BlockCommon,
417    },
418    #[serde(other)]
419    Unknown,
420}
421
422impl AsIdentifier<BlockId> for Block {
423    fn as_id(&self) -> &BlockId {
424        use Block::*;
425        match self {
426            Paragraph { common, .. }
427            | Heading1 { common, .. }
428            | Heading2 { common, .. }
429            | Heading3 { common, .. }
430            | Callout { common, .. }
431            | Quote { common, .. }
432            | BulletedListItem { common, .. }
433            | NumberedListItem { common, .. }
434            | ToDo { common, .. }
435            | Toggle { common, .. }
436            | Code { common, .. }
437            | ChildPage { common, .. }
438            | ChildDatabase { common, .. }
439            | Embed { common, .. }
440            | Image { common, .. }
441            | Video { common, .. }
442            | File { common, .. }
443            | Pdf { common, .. }
444            | Bookmark { common, .. }
445            | Equation { common, .. }
446            | Divider { common, .. }
447            | TableOfContents { common, .. }
448            | Breadcrumb { common, .. }
449            | ColumnList { common, .. }
450            | Column { common, .. }
451            | LinkPreview { common, .. }
452            | Template { common, .. }
453            | LinkToPage { common, .. }
454            | SyncedBlock { common, .. }
455            | Table { common, .. }
456            | TableRow { common, .. }
457            | Unsupported { common, .. } => &common.id,
458            Unknown => {
459                panic!("Trying to reference identifier for unknown block!")
460            }
461        }
462    }
463}
464
465impl Into<CreateBlock> for Block {
466    fn into(self) -> CreateBlock {
467        match self {
468            Block::Paragraph { paragraph, .. } => CreateBlock::Paragraph { paragraph },
469            Block::Heading1 { heading_1, .. } => CreateBlock::Heading1 { heading_1 },
470            Block::Heading2 { heading_2, .. } => CreateBlock::Heading2 { heading_2 },
471            Block::Heading3 { heading_3, .. } => CreateBlock::Heading3 { heading_3 },
472            Block::Callout { callout, .. } => CreateBlock::Callout { callout },
473            Block::Quote { quote, .. } => CreateBlock::Quote { quote },
474            Block::BulletedListItem {
475                bulleted_list_item, ..
476            } => CreateBlock::BulletedListItem { bulleted_list_item },
477            Block::NumberedListItem {
478                numbered_list_item, ..
479            } => CreateBlock::NumberedListItem { numbered_list_item },
480            Block::ToDo { to_do, .. } => CreateBlock::ToDo { to_do },
481            Block::Toggle { toggle, .. } => CreateBlock::Toggle { toggle },
482            Block::Code { code, .. } => CreateBlock::Code { code },
483            Block::ChildPage { child_page, .. } => CreateBlock::ChildPage { child_page },
484            Block::ChildDatabase { child_page, .. } => CreateBlock::ChildDatabase { child_page },
485            Block::Embed { embed, .. } => CreateBlock::Embed { embed },
486            Block::Image { image, .. } => CreateBlock::Image { image },
487            Block::Video { video, .. } => CreateBlock::Video { video },
488            Block::File { file, caption, .. } => CreateBlock::File { file, caption },
489            Block::Pdf { pdf, .. } => CreateBlock::Pdf { pdf },
490            Block::Bookmark { bookmark, .. } => CreateBlock::Bookmark { bookmark },
491            Block::Equation { equation, .. } => CreateBlock::Equation { equation },
492            Block::Divider { .. } => CreateBlock::Divider {},
493            Block::TableOfContents {
494                table_of_contents, ..
495            } => CreateBlock::TableOfContents { table_of_contents },
496            Block::Breadcrumb { .. } => CreateBlock::Breadcrumb {},
497            Block::ColumnList { column_list, .. } => CreateBlock::ColumnList { column_list },
498            Block::Column { column, .. } => CreateBlock::Column { column },
499
500            Block::LinkPreview { link_preview, .. } => CreateBlock::LinkPreview { link_preview },
501            Block::Template { template, .. } => CreateBlock::Template { template },
502            Block::LinkToPage { link_to_page, .. } => CreateBlock::LinkToPage { link_to_page },
503            Block::Table { table, .. } => CreateBlock::Table { table },
504            Block::SyncedBlock { synced_block, .. } => CreateBlock::SyncedBlock { synced_block },
505            Block::TableRow { table_row, .. } => CreateBlock::TableRow { table_row },
506            Block::Unsupported { .. } => CreateBlock::Unsupported,
507            Block::Unknown => CreateBlock::Unknown,
508        }
509    }
510}
511
512#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
513#[serde(tag = "type")]
514#[serde(rename_all = "snake_case")]
515pub enum CreateBlock {
516    Paragraph {
517        paragraph: TextAndChildren,
518    },
519    #[serde(rename = "heading_1")]
520    Heading1 {
521        heading_1: Text,
522    },
523    #[serde(rename = "heading_2")]
524    Heading2 {
525        heading_2: Text,
526    },
527    #[serde(rename = "heading_3")]
528    Heading3 {
529        heading_3: Text,
530    },
531    Callout {
532        callout: Callout,
533    },
534    Quote {
535        quote: TextAndChildren,
536    },
537    BulletedListItem {
538        bulleted_list_item: TextAndChildren,
539    },
540    NumberedListItem {
541        numbered_list_item: TextAndChildren,
542    },
543    ToDo {
544        to_do: ToDoFields,
545    },
546    Toggle {
547        toggle: TextAndChildren,
548    },
549    Code {
550        code: CodeFields,
551    },
552    ChildPage {
553        child_page: ChildPageFields,
554    },
555    ChildDatabase {
556        child_page: ChildDatabaseFields,
557    },
558    Embed {
559        embed: EmbedFields,
560    },
561    Image {
562        image: FileObject,
563    },
564    Video {
565        video: FileObject,
566    },
567    File {
568        file: FileObject,
569        caption: Text,
570    },
571    Pdf {
572        pdf: FileObject,
573    },
574    Bookmark {
575        bookmark: BookmarkFields,
576    },
577    Equation {
578        equation: Equation,
579    },
580    Divider,
581    TableOfContents {
582        table_of_contents: TableOfContents,
583    },
584    Breadcrumb,
585    ColumnList {
586        column_list: ColumnListFields,
587    },
588    Column {
589        column: ColumnFields,
590    },
591    LinkPreview {
592        link_preview: LinkPreviewFields,
593    },
594    Template {
595        template: TemplateFields,
596    },
597    LinkToPage {
598        link_to_page: LinkToPageFields,
599    },
600    Table {
601        table: TableFields,
602    },
603    SyncedBlock {
604        synced_block: SyncedBlockFields,
605    },
606    TableRow {
607        table_row: TableRowFields,
608    },
609    Unsupported,
610    #[serde(other)]
611    Unknown,
612}