simple_notion/
notion_data_base.rs1use std::any::TypeId;
2
3pub type DataBaseElement = (String, json::JsonValue);
4
5#[derive(Debug, Clone, Default)]
6pub struct NotionRelation {
7 pub ids: Vec<String>,
8 pub has_more: bool,
9}
10
11impl NotionRelation {
12 pub fn new(ids: Vec<String>, has_more: bool) -> Self {
13 Self {
14 ids,
15 has_more,
16 }
17 }
18}
19
20#[derive(Debug, Clone, Default)]
21pub struct NotionFormula {
22 pub type_name: String,
23 pub result_str: String,
24 pub result_number: f64,
25}
26
27impl NotionFormula {
28 pub fn new(type_name: String, result_str: String, result_number: f64) -> Self {
29 Self {
30 type_name,
31 result_str,
32 result_number,
33 }
34 }
35
36 pub fn get_type_id(&self) -> TypeId {
37 if self.result_str.is_empty() {
38 TypeId::of::<f64>()
39 } else {
40 TypeId::of::<String>()
41 }
42 }
43}
44
45#[derive(Debug, Clone, Default)]
46pub struct NotionDate {
47 pub start: Option<String>,
48 pub end: Option<String>,
49 pub time_zone: Option<String>,
50}
51
52impl NotionDate {
53 pub fn new(start: Option<String>, end: Option<String>, time_zone: Option<String>) -> Self {
54 Self {
55 start,
56 end,
57 time_zone,
58 }
59 }
60}
61
62#[derive(Debug, Clone)]
63pub struct NotionFile {
64 pub name: String,
65 pub url: String
66}
67
68impl NotionFile {
69 pub fn new(name: String, url: String) -> Self {
70 Self {
71 name,
72 url,
73 }
74 }
75}
76
77#[derive(Debug, Clone)]
78pub enum DataType {
79 Title(String),
80 URL(String),
81 Text(String),
82 Number(f64),
83 Files(Vec<NotionFile>),
84 Select(String),
85 MultiSelect(Vec<String>),
86 CheckBox(bool),
87 EMail(String),
88 Status(String),
89 People(Vec<String>),
90 Date(NotionDate),
91 CreatedBy(String),
92 Formula(NotionFormula),
93 PhoneNumber(String),
94 Relation(NotionRelation),
95 Rollup(Vec<json::JsonValue>),
96 CreatedTime(String),
97 LastEditedTime(String),
98 LastEditedBy(String),
99 Uknown,
100 Null(String),
102}
103
104impl DataType {
105 pub fn to_json(&self, property_name: &str) -> String {
106 match self {
107 DataType::Title(_title) => {
108 let object = json::JsonValue::new_object();
109
110 format!("\"{}\": {}", property_name, object.dump())
111 }
112 DataType::Number(number) => {
113 format!("\"{}\": {{ \"{}\": {} }}", property_name, crate::non_magic::notion::NOTION_TYPE_NUMBER, number)
114 }
115 _ => String::new(),
116 }
117 }
118}
119
120pub struct NotionDataBase {
121 content: Vec<Vec<DataBaseElement>>,
122}
123
124impl NotionDataBase {
125 pub fn new(content: Vec<Vec<DataBaseElement>>) -> Self {
126 Self { content }
127 }
128
129 pub fn get_line_count(&self) -> usize {
130 self.content.len()
131 }
132
133 pub fn get_column_count(&self) -> usize {
134 match self.content.first() {
135 Some(first) => {
136 first.len()
137 }
138 None => 0,
139 }
140 }
141
142 pub fn get_first_at(&self, line: usize) -> Option<DataBaseElement> {
144 self.get_at(line, 0)
145 }
146
147 #[deprecated(note="Notion not follow any logic in data base index")]
149 pub fn get_last_at(&self, line: usize) -> Option<DataBaseElement> {
150 self.get_at(line, self.get_column_count() - 1)
151 }
152
153 pub fn get_at(&self, mut line: usize, mut column: usize) -> Option<DataBaseElement> {
155 line = (self.get_line_count() as i32 - 1_i32 - line as i32) as usize;
156 column = (self.get_column_count() as i32 - 1_i32 - column as i32) as usize;
157
158 match self.content.get(line) {
159 Some(value) => {
160 match value.get(column) {
161 Some(value) => {
162 Some(value.clone())
163 }
164 None => None,
165 }
166 }
167 None => None,
168 }
169 }
170
171 pub fn get(&self, parser: &crate::parser::NotionResponseParser, line: &str, column_name: &str) -> Option<DataBaseElement> {
172 for table_line in self.content.iter() {
173 let mut name = String::new();
174 match parser.parse_element(table_line.last().unwrap().1.clone()) {
175 DataType::Title(title) => {
176 name = title;
177 }
178 _ => (),
179 }
180 if name == line {
181 for column in table_line {
182 if column.0 == column_name {
183 return Some(column.clone());
184 }
185 }
186 }
187 }
188 None
189 }
190
191 pub fn get_line_list(&self, parser: &crate::parser::NotionResponseParser) -> Vec<String> {
193 let mut result = Vec::<String>::new();
194
195 for table_line in self.content.iter() {
196 let mut name = String::new();
197 match parser.parse_element(table_line.last().unwrap().1.clone()) {
198 DataType::Title(title) => {
199 name = title;
200 }
201 _ => (),
202 }
203
204 result.push(name);
205 }
206
207 result
208 }
209
210 pub fn get_column_list(&self) -> Vec<String> {
212 let mut result = Vec::<String>::new();
213
214 match self.content.first() {
215 Some(first) => {
216 for column in first {
217 result.push(column.0.clone());
218 }
219 }
220 None => (),
221 }
222
223 result
224 }
225
226 pub fn get_all(&self, parser: &crate::parser::NotionResponseParser) -> Vec<Vec<DataType>> {
228 let mut result = Vec::<Vec<DataType>>::new();
229
230 let lines = self.get_line_list(&parser);
231 let columns = self.get_column_list();
232
233 for line in lines.iter() {
234 let mut out = Vec::<DataType>::new();
235 for column in columns.iter() {
236 match self.get(&parser, line, column) {
237 Some(value) => {
238 out.push(parser.parse_element(value.1));
239 }
240 None => (),
241 }
242 }
243 result.push(out);
244 }
245
246 result
247 }
248}