diff options
author | 2023-02-26 03:08:54 +1100 | |
---|---|---|
committer | 2023-02-25 08:08:54 -0800 | |
commit | 1ba9846bad1d5c927e0d7658a59097992ef56b60 (patch) | |
tree | c1466c8e6ffc7162c864ff2a6e7c34c512e3c8f4 /src/models/block.rs | |
parent | 97764fb864ae1ab6046749fe5cabe00f508b0c61 (diff) | |
download | notion-1ba9846bad1d5c927e0d7658a59097992ef56b60.tar.gz notion-1ba9846bad1d5c927e0d7658a59097992ef56b60.tar.zst notion-1ba9846bad1d5c927e0d7658a59097992ef56b60.zip |
Add new CreateBlock children to page creation (#49)
* extract block to mod
* add CreateBlock struct, implement Into<CreateBlock> for Block, and add children to PageCreateRequest
* move tests into block mod and fix up use
Diffstat (limited to 'src/models/block.rs')
-rw-r--r-- | src/models/block.rs | 612 |
1 files changed, 612 insertions, 0 deletions
diff --git a/src/models/block.rs b/src/models/block.rs new file mode 100644 index 0000000..0d1b651 --- /dev/null +++ b/src/models/block.rs @@ -0,0 +1,612 @@ +use chrono::{DateTime, Utc}; +use serde::{Deserialize, Serialize}; + +use crate::ids::{AsIdentifier, BlockId, DatabaseId, PageId}; +use crate::models::text::{RichText, TextColor}; +use crate::models::users::UserCommon; + +mod tests; + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct BlockCommon { + pub id: BlockId, + pub created_time: DateTime<Utc>, + pub last_edited_time: DateTime<Utc>, + pub has_children: bool, + pub created_by: UserCommon, + pub last_edited_by: UserCommon, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct TextAndChildren { + pub rich_text: Vec<RichText>, + #[serde(skip_serializing_if = "Option::is_none")] + pub children: Option<Vec<Block>>, + pub color: TextColor, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct Text { + pub rich_text: Vec<RichText>, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct InternalFileObject { + url: String, + expiry_time: DateTime<Utc>, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct ExternalFileObject { + url: String, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +#[serde(tag = "type")] +#[serde(rename_all = "snake_case")] +pub enum FileOrEmojiObject { + Emoji { emoji: String }, + File { file: InternalFileObject }, + External { external: ExternalFileObject }, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +#[serde(tag = "type")] +#[serde(rename_all = "snake_case")] +pub enum FileObject { + File { file: InternalFileObject }, + External { external: ExternalFileObject }, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct Callout { + pub rich_text: Vec<RichText>, + pub icon: FileOrEmojiObject, + pub color: TextColor, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct ToDoFields { + pub rich_text: Vec<RichText>, + pub checked: bool, + #[serde(skip_serializing_if = "Option::is_none")] + pub children: Option<Vec<Block>>, + pub color: TextColor, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct ChildPageFields { + pub title: String, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct ChildDatabaseFields { + pub title: String, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct EmbedFields { + pub url: String, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct BookmarkFields { + pub url: String, + pub caption: Vec<RichText>, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +#[serde(rename_all = "lowercase")] +pub enum CodeLanguage { + Abap, + Arduino, + Bash, + Basic, + C, + Clojure, + Coffeescript, + #[serde(rename = "c++")] + CPlusPlus, + #[serde(rename = "c#")] + CSharp, + Css, + Dart, + Diff, + Docker, + Elixir, + Elm, + Erlang, + Flow, + Fortran, + #[serde(rename = "f#")] + FSharp, + Gherkin, + Glsl, + Go, + Graphql, + Groovy, + Haskell, + Html, + Java, + Javascript, + Json, + Julia, + Kotlin, + Latex, + Less, + Lisp, + Livescript, + Lua, + Makefile, + Markdown, + Markup, + Matlab, + Mermaid, + Nix, + #[serde(rename = "objective-c")] + ObjectiveC, + Ocaml, + Pascal, + Perl, + Php, + #[serde(rename = "plain text")] + PlainText, + Powershell, + Prolog, + Protobuf, + Python, + R, + Reason, + Ruby, + Rust, + Sass, + Scala, + Scheme, + Scss, + Shell, + Sql, + Swift, + Typescript, + #[serde(rename = "vb.net")] + VbNet, + Verilog, + Vhdl, + #[serde(rename = "visual basic")] + VisualBasic, + Webassembly, + Xml, + Yaml, + #[serde(rename = "java/c/c++/c#")] + JavaCAndCPlusPlusAndCSharp, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct CodeFields { + pub rich_text: Vec<RichText>, + pub caption: Vec<RichText>, + pub language: CodeLanguage, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct Equation { + pub expression: String, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct TableOfContents { + pub color: TextColor, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct ColumnListFields { + pub children: Vec<Block>, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct ColumnFields { + pub children: Vec<Block>, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct LinkPreviewFields { + pub url: String, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct TemplateFields { + pub rich_text: Vec<RichText>, + pub children: Vec<Block>, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +#[serde(tag = "type")] +#[serde(rename_all = "snake_case")] +pub enum LinkToPageFields { + PageId { page_id: PageId }, + DatabaseId { database_id: DatabaseId }, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct SyncedFromObject { + pub block_id: BlockId, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct SyncedBlockFields { + pub synced_from: Option<SyncedFromObject>, + pub children: Vec<Block>, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct TableFields { + pub table_width: u64, + pub has_column_header: bool, + pub has_row_header: bool, + pub children: Vec<Block>, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +pub struct TableRowFields { + pub cells: Vec<RichText>, +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +#[serde(tag = "type")] +#[serde(rename_all = "snake_case")] +pub enum Block { + Paragraph { + #[serde(flatten)] + common: BlockCommon, + paragraph: TextAndChildren, + }, + #[serde(rename = "heading_1")] + Heading1 { + #[serde(flatten)] + common: BlockCommon, + heading_1: Text, + }, + #[serde(rename = "heading_2")] + Heading2 { + #[serde(flatten)] + common: BlockCommon, + heading_2: Text, + }, + #[serde(rename = "heading_3")] + Heading3 { + #[serde(flatten)] + common: BlockCommon, + heading_3: Text, + }, + Callout { + #[serde(flatten)] + common: BlockCommon, + callout: Callout, + }, + Quote { + #[serde(flatten)] + common: BlockCommon, + quote: TextAndChildren, + }, + BulletedListItem { + #[serde(flatten)] + common: BlockCommon, + bulleted_list_item: TextAndChildren, + }, + NumberedListItem { + #[serde(flatten)] + common: BlockCommon, + numbered_list_item: TextAndChildren, + }, + ToDo { + #[serde(flatten)] + common: BlockCommon, + to_do: ToDoFields, + }, + Toggle { + #[serde(flatten)] + common: BlockCommon, + toggle: TextAndChildren, + }, + Code { + #[serde(flatten)] + common: BlockCommon, + code: CodeFields, + }, + ChildPage { + #[serde(flatten)] + common: BlockCommon, + child_page: ChildPageFields, + }, + ChildDatabase { + #[serde(flatten)] + common: BlockCommon, + child_page: ChildDatabaseFields, + }, + Embed { + #[serde(flatten)] + common: BlockCommon, + embed: EmbedFields, + }, + Image { + #[serde(flatten)] + common: BlockCommon, + image: FileObject, + }, + Video { + #[serde(flatten)] + common: BlockCommon, + video: FileObject, + }, + File { + #[serde(flatten)] + common: BlockCommon, + file: FileObject, + caption: Text, + }, + Pdf { + #[serde(flatten)] + common: BlockCommon, + pdf: FileObject, + }, + Bookmark { + #[serde(flatten)] + common: BlockCommon, + bookmark: BookmarkFields, + }, + Equation { + #[serde(flatten)] + common: BlockCommon, + equation: Equation, + }, + Divider { + #[serde(flatten)] + common: BlockCommon, + }, + TableOfContents { + #[serde(flatten)] + common: BlockCommon, + table_of_contents: TableOfContents, + }, + Breadcrumb { + #[serde(flatten)] + common: BlockCommon, + }, + ColumnList { + #[serde(flatten)] + common: BlockCommon, + column_list: ColumnListFields, + }, + Column { + #[serde(flatten)] + common: BlockCommon, + column: ColumnFields, + }, + LinkPreview { + #[serde(flatten)] + common: BlockCommon, + link_preview: LinkPreviewFields, + }, + Template { + #[serde(flatten)] + common: BlockCommon, + template: TemplateFields, + }, + LinkToPage { + #[serde(flatten)] + common: BlockCommon, + link_to_page: LinkToPageFields, + }, + Table { + #[serde(flatten)] + common: BlockCommon, + table: TableFields, + }, + SyncedBlock { + #[serde(flatten)] + common: BlockCommon, + synced_block: SyncedBlockFields, + }, + TableRow { + #[serde(flatten)] + common: BlockCommon, + table_row: TableRowFields, + }, + Unsupported { + #[serde(flatten)] + common: BlockCommon, + }, + #[serde(other)] + Unknown, +} + +impl AsIdentifier<BlockId> for Block { + fn as_id(&self) -> &BlockId { + use Block::*; + match self { + Paragraph { common, .. } + | Heading1 { common, .. } + | Heading2 { common, .. } + | Heading3 { common, .. } + | Callout { common, .. } + | Quote { common, .. } + | BulletedListItem { common, .. } + | NumberedListItem { common, .. } + | ToDo { common, .. } + | Toggle { common, .. } + | Code { common, .. } + | ChildPage { common, .. } + | ChildDatabase { common, .. } + | Embed { common, .. } + | Image { common, .. } + | Video { common, .. } + | File { common, .. } + | Pdf { common, .. } + | Bookmark { common, .. } + | Equation { common, .. } + | Divider { common, .. } + | TableOfContents { common, .. } + | Breadcrumb { common, .. } + | ColumnList { common, .. } + | Column { common, .. } + | LinkPreview { common, .. } + | Template { common, .. } + | LinkToPage { common, .. } + | SyncedBlock { common, .. } + | Table { common, .. } + | TableRow { common, .. } + | Unsupported { common, .. } => &common.id, + Unknown => { + panic!("Trying to reference identifier for unknown block!") + } + } + } +} + +impl Into<CreateBlock> for Block { + fn into(self) -> CreateBlock { + match self { + Block::Paragraph { paragraph, .. } => CreateBlock::Paragraph { paragraph }, + Block::Heading1 { heading_1, .. } => CreateBlock::Heading1 { heading_1 }, + Block::Heading2 { heading_2, .. } => CreateBlock::Heading2 { heading_2 }, + Block::Heading3 { heading_3, .. } => CreateBlock::Heading3 { heading_3 }, + Block::Callout { callout, .. } => CreateBlock::Callout { callout }, + Block::Quote { quote, .. } => CreateBlock::Quote { quote }, + Block::BulletedListItem { + bulleted_list_item, .. + } => CreateBlock::BulletedListItem { bulleted_list_item }, + Block::NumberedListItem { + numbered_list_item, .. + } => CreateBlock::NumberedListItem { numbered_list_item }, + Block::ToDo { to_do, .. } => CreateBlock::ToDo { to_do }, + Block::Toggle { toggle, .. } => CreateBlock::Toggle { toggle }, + Block::Code { code, .. } => CreateBlock::Code { code }, + Block::ChildPage { child_page, .. } => CreateBlock::ChildPage { child_page }, + Block::ChildDatabase { child_page, .. } => CreateBlock::ChildDatabase { child_page }, + Block::Embed { embed, .. } => CreateBlock::Embed { embed }, + Block::Image { image, .. } => CreateBlock::Image { image }, + Block::Video { video, .. } => CreateBlock::Video { video }, + Block::File { file, caption, .. } => CreateBlock::File { file, caption }, + Block::Pdf { pdf, .. } => CreateBlock::Pdf { pdf }, + Block::Bookmark { bookmark, .. } => CreateBlock::Bookmark { bookmark }, + Block::Equation { equation, .. } => CreateBlock::Equation { equation }, + Block::Divider { .. } => CreateBlock::Divider {}, + Block::TableOfContents { + table_of_contents, .. + } => CreateBlock::TableOfContents { table_of_contents }, + Block::Breadcrumb { .. } => CreateBlock::Breadcrumb {}, + Block::ColumnList { column_list, .. } => CreateBlock::ColumnList { column_list }, + Block::Column { column, .. } => CreateBlock::Column { column }, + + Block::LinkPreview { link_preview, .. } => CreateBlock::LinkPreview { link_preview }, + Block::Template { template, .. } => CreateBlock::Template { template }, + Block::LinkToPage { link_to_page, .. } => CreateBlock::LinkToPage { link_to_page }, + Block::Table { table, .. } => CreateBlock::Table { table }, + Block::SyncedBlock { synced_block, .. } => CreateBlock::SyncedBlock { synced_block }, + Block::TableRow { table_row, .. } => CreateBlock::TableRow { table_row }, + Block::Unsupported { .. } => CreateBlock::Unsupported, + Block::Unknown => CreateBlock::Unknown, + } + } +} + +#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)] +#[serde(tag = "type")] +#[serde(rename_all = "snake_case")] +pub enum CreateBlock { + Paragraph { + paragraph: TextAndChildren, + }, + #[serde(rename = "heading_1")] + Heading1 { + heading_1: Text, + }, + #[serde(rename = "heading_2")] + Heading2 { + heading_2: Text, + }, + #[serde(rename = "heading_3")] + Heading3 { + heading_3: Text, + }, + Callout { + callout: Callout, + }, + Quote { + quote: TextAndChildren, + }, + BulletedListItem { + bulleted_list_item: TextAndChildren, + }, + NumberedListItem { + numbered_list_item: TextAndChildren, + }, + ToDo { + to_do: ToDoFields, + }, + Toggle { + toggle: TextAndChildren, + }, + Code { + code: CodeFields, + }, + ChildPage { + child_page: ChildPageFields, + }, + ChildDatabase { + child_page: ChildDatabaseFields, + }, + Embed { + embed: EmbedFields, + }, + Image { + image: FileObject, + }, + Video { + video: FileObject, + }, + File { + file: FileObject, + caption: Text, + }, + Pdf { + pdf: FileObject, + }, + Bookmark { + bookmark: BookmarkFields, + }, + Equation { + equation: Equation, + }, + Divider, + TableOfContents { + table_of_contents: TableOfContents, + }, + Breadcrumb, + ColumnList { + column_list: ColumnListFields, + }, + Column { + column: ColumnFields, + }, + LinkPreview { + link_preview: LinkPreviewFields, + }, + Template { + template: TemplateFields, + }, + LinkToPage { + link_to_page: LinkToPageFields, + }, + Table { + table: TableFields, + }, + SyncedBlock { + synced_block: SyncedBlockFields, + }, + TableRow { + table_row: TableRowFields, + }, + Unsupported, + #[serde(other)] + Unknown, +} |