notionrs_types/object/block/
heading.rs1use serde::{Deserialize, Serialize};
2
3use crate::color_setters;
4
5#[derive(Deserialize, Serialize, Debug, Default, Clone)]
10pub struct HeadingBlock {
11 pub rich_text: Vec<crate::object::rich_text::RichText>,
13
14 pub color: crate::object::color::Color,
16
17 pub is_toggleable: bool,
22
23 #[serde(skip_serializing_if = "Option::is_none")]
26 pub children: Option<Vec<super::Block>>,
27}
28
29impl HeadingBlock {
30 pub fn rich_text(mut self, rich_text: Vec<crate::object::rich_text::RichText>) -> Self {
31 self.rich_text = rich_text;
32 self
33 }
34
35 pub fn children(mut self, children: Vec<super::Block>) -> Self {
36 self.children = Some(children);
37 self
38 }
39
40 color_setters!(self, self.color);
41
42 pub fn is_toggleable(mut self, is_toggleable: bool) -> Self {
43 self.is_toggleable = is_toggleable;
44 self
45 }
46}
47
48impl<T> From<T> for HeadingBlock
49where
50 T: AsRef<str>,
51{
52 fn from(plain_text: T) -> Self {
53 let rich_text = crate::object::rich_text::RichText::from(plain_text.as_ref().to_string());
54 Self::default().rich_text(vec![rich_text])
55 }
56}
57
58impl std::fmt::Display for HeadingBlock {
59 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
60 write!(
61 f,
62 "{}",
63 self.rich_text
64 .iter()
65 .map(|t| { t.to_string() })
66 .collect::<String>()
67 )
68 }
69}
70
71#[cfg(test)]
78mod unit_tests {
79
80 use super::HeadingBlock;
81
82 #[test]
83 fn deserialize_block_heading() {
84 let json_data = r#"
85 {
86 "rich_text": [
87 {
88 "type": "text",
89 "text": {
90 "content": "Heading 1",
91 "link": null
92 },
93 "annotations": {
94 "bold": false,
95 "italic": false,
96 "strikethrough": false,
97 "underline": false,
98 "code": false,
99 "color": "default"
100 },
101 "plain_text": "Heading",
102 "href": null
103 }
104 ],
105 "is_toggleable": false,
106 "color": "default"
107 }
108 "#;
109
110 let heading: HeadingBlock = serde_json::from_str::<HeadingBlock>(json_data).unwrap();
111
112 assert_eq!(heading.color, crate::object::color::Color::Default);
113
114 assert!(!heading.is_toggleable);
115
116 let rich_text = heading.rich_text.first().unwrap();
117
118 match rich_text {
119 crate::object::rich_text::RichText::Text {
120 annotations,
121 plain_text,
122 href,
123 ..
124 } => {
125 assert_eq!(plain_text, "Heading");
126 assert_eq!(*href, None);
127
128 assert!(!annotations.bold);
129 assert!(!annotations.code);
130 assert!(!annotations.strikethrough);
131 assert!(!annotations.underline);
132 assert!(!annotations.italic);
133 assert_eq!(annotations.color, crate::object::color::Color::Default)
134 }
135 _ => panic!(),
136 }
137 }
138}