simple_notion/
parser.rs

1use crate::notion_data_base::{DataBaseElement, DataType, NotionFile, NotionDate, NotionFormula, NotionRelation};
2use crate::non_magic::notion::*;
3
4pub struct NotionResponseParser {
5    value: json::JsonValue,
6}
7
8impl NotionResponseParser {
9    pub fn new<T: ToString>(buffer: T) -> Self {
10        Self {
11            value: json::parse(&buffer.to_string()).unwrap(),
12        }
13    }
14
15    pub fn parse_table(&self) -> Vec<Vec<DataBaseElement>> {
16        let mut result = Vec::<Vec<DataBaseElement>>::new();
17
18        let results = self.value[NOTION_JSON_RESULTS].clone();
19        for i in results.members() {
20            let mut elements: Vec<DataBaseElement> = Vec::new();
21            for i in i[NOTION_JSON_PROPERTIES].entries() {
22                let out = (i.0.to_owned(), i.1.clone());
23                elements.push(out);
24            }
25            result.push(elements);
26        }
27
28        result
29    }
30
31    pub fn parse_element(&self, element: json::JsonValue) -> DataType {
32        match element["type"].as_str().unwrap() {
33            NOTION_TYPE_TITLE => {
34                let last = crate::get_last!(element);
35                match last.1.members().last().unwrap()[NOTION_KEYWORD_TEXT][NOTION_KEYWORD_CONTENT].as_str() {
36                    Some(value) => {
37                        DataType::Title(value.to_owned())
38                    }
39                    None => DataType::Null(NOTION_TYPE_TITLE.to_owned()),
40                }
41            }
42            NOTION_TYPE_FILES => {
43                let last = crate::get_last!(element);
44                let mut out = Vec::<NotionFile>::new();
45                for file in last.1.members() {
46                    if file["type"] != NOTION_KEYWORD_EXTERNAL {
47                        match file[NOTION_KEYWORD_NAME].as_str() {
48                            Some(name) => {
49                                match file[NOTION_KEYWORD_FILE][NOTION_KEYWORD_URL].as_str() {
50                                    Some(file) => {
51                                        out.push(NotionFile::new(name.to_owned(), file.to_owned()));
52                                    }
53                                    None => (),
54                                }
55                            }
56                            None => (),
57                        }
58                    } else {
59                        match file[NOTION_KEYWORD_NAME].as_str() {
60                            Some(name) => {
61                                match file[NOTION_KEYWORD_EXTERNAL][NOTION_KEYWORD_URL].as_str() {
62                                    Some(file) => {
63                                        out.push(NotionFile::new(name.to_owned(), file.to_owned()));
64                                    }
65                                    None => (),
66                                }
67                            }
68                            None => (),
69                        }
70                    }
71                }
72                DataType::Files(out)
73            }
74            NOTION_TYPE_SELECT => {
75                let last = crate::get_last!(element);
76                match last.1[NOTION_KEYWORD_NAME].as_str() {
77                    Some(value) => {
78                        DataType::Select(value.to_owned())
79                    }
80                    None => DataType::Null(NOTION_TYPE_SELECT.to_owned()),
81                }
82            }
83            NOTION_TYPE_MULTI_SELECT => {
84                let last = crate::get_last!(element);
85                let mut out = Vec::<String>::new();
86                for select in last.1.members() {
87                    match select[NOTION_KEYWORD_NAME].as_str() {
88                        Some(select) => {
89                            out.push(select.to_owned())        
90                        }
91                        None => (),
92                    }
93                }
94                DataType::MultiSelect(out)
95            }
96            NOTION_TYPE_NUMBER => {
97                let last = crate::get_last!(element);
98                match last.1.as_f64() {
99                    Some(number) => {
100                        DataType::Number(number)
101                    }
102                    None => DataType::Null(NOTION_TYPE_NUMBER.to_owned()),
103                }
104            }
105            NOTION_TYPE_CHECKBOX => {
106                let last = crate::get_last!(element);
107                match last.1.as_bool() {
108                    Some(bool) => {
109                        DataType::CheckBox(bool)
110                    }
111                    None => DataType::Null(NOTION_TYPE_CHECKBOX.to_owned())
112                }
113            }
114            NOTION_TYPE_URL => {
115                let last = crate::get_last!(element);
116                match last.1.as_str() {
117                    Some(url) => {
118                        DataType::URL(url.to_owned())
119                    }
120                    None => DataType::Null(NOTION_TYPE_URL.to_owned())
121                }
122            }
123            NOTION_TYPE_EMAIL => {
124                let last = crate::get_last!(element);
125                match last.1.as_str() {
126                    Some(email) => {
127                        DataType::EMail(email.to_owned())
128                    }
129                    None => DataType::Null(NOTION_TYPE_EMAIL.to_owned()),
130                }
131            }
132            NOTION_TYPE_STATUS => {
133                let last = crate::get_last!(element);
134                match last.1[NOTION_KEYWORD_NAME].as_str() {
135                    Some(status) => {
136                        DataType::Status(status.to_owned())
137                    }
138                    None => DataType::Null(NOTION_TYPE_STATUS.to_owned()),
139                }
140            }
141            NOTION_TYPE_PEOPLE => {
142                let last = crate::get_last!(element);
143                let mut out = Vec::<String>::new();
144                for select in last.1.members() {
145                    match select[NOTION_KEYWORD_ID].as_str() {
146                        Some(people) => {
147                            out.push(people.to_owned());
148                        }
149                        None => (),
150                    }
151                }
152                DataType::People(out)
153            }
154            NOTION_TYPE_CREATED_BY => {
155                let last = crate::get_last!(element);
156                match last.1["id"].as_str() {
157                    Some(id) => {
158                        DataType::CreatedBy(id.to_owned())       
159                    }
160                    None => {
161                        DataType::Null(String::from(NOTION_TYPE_CREATED_BY))
162                    }
163                }
164            }
165            NOTION_TYPE_FORMULA => {
166                
167                let last = crate::get_last!(element);
168                
169                let mut formula = NotionFormula::default();
170                
171                match last.1["type"].as_str() {
172                    Some(type_name) => {
173                        formula.type_name = type_name.to_owned();
174                    }
175                    None => (),
176                }
177                
178                if !formula.type_name.is_empty() {
179                    match last.1[formula.type_name.clone()].as_str() {
180                        Some(result) => {
181                            formula.result_str = result.to_owned();
182                        }
183                        None => {
184                            match last.1[formula.type_name.clone()].as_f64() {
185                                Some(result) => {
186                                    formula.result_number = result.to_owned();
187                                }
188                                None => return DataType::Null(NOTION_TYPE_FORMULA.to_owned()),
189                            }
190                        }
191                    }
192                }
193                
194                DataType::Formula(formula)
195            }
196            NOTION_TYPE_PHONE_NUMBER => {
197                let last = crate::get_last!(element);
198                
199                match last.1.as_str() {
200                    Some(phone_number) => {
201                        DataType::PhoneNumber(phone_number.to_owned())
202                    }
203                    None => DataType::Null(NOTION_TYPE_PHONE_NUMBER.to_owned())
204                }
205            }
206            NOTION_TYPE_RELATION => {
207                let last = crate::get_last!(element);
208                let mut notion_relation = NotionRelation::default();
209                
210                match last.1.as_bool() {
211                    Some(has_more) => {
212                        notion_relation.has_more = has_more;
213                    }
214                    None => (),
215                }
216                
217                for relation in element[NOTION_TYPE_RELATION].members() {
218                    match relation[NOTION_KEYWORD_ID].as_str() {
219                        Some(id) => {
220                            notion_relation.ids.push(id.to_owned());
221                        }
222                        None => (),
223                    } 
224                }
225                
226                if !notion_relation.ids.is_empty() {
227                    DataType::Relation(notion_relation)
228                } else {
229                    DataType::Null(NOTION_TYPE_RELATION.to_owned())   
230                }
231            }
232            NOTION_TYPE_DATE => {
233                let last = crate::get_last!(element);
234
235                let mut notion_date = NotionDate::default();
236                
237                match last.1[NOTION_KEYWORD_START].as_str() {
238                    Some(date) => {
239                        notion_date.start = Some(date.to_owned());
240                    }
241                    None => (),
242                }
243                
244                match last.1[NOTION_KEYWORD_END].as_str() {
245                    Some(date) => {
246                        notion_date.end = Some(date.to_owned());
247                    }
248                    None => (),
249                }
250                
251                match last.1[NOTION_KEYWORD_TIME_ZONE].as_str() {
252                    Some(date) => {
253                        notion_date.time_zone = Some(date.to_owned());
254                    }
255                    None => (),
256                }
257
258                DataType::Date(notion_date)
259            }
260            NOTION_TYPE_ROLLUP => {
261                let mut out = Vec::<json::JsonValue>::new(); 
262                for member in element[NOTION_TYPE_ROLLUP][NOTION_KEYWORD_ARRAY].members() {
263                    out.push(member.clone());
264                }
265                
266                if out.is_empty() {
267                    DataType::Null(NOTION_TYPE_ROLLUP.to_owned())
268                } else {
269                    DataType::Rollup(out)
270                }
271            }
272            NOTION_TYPE_CREATED_TIME => {
273                match element[NOTION_TYPE_CREATED_TIME].as_str() {
274                    Some(time) => DataType::CreatedTime(time.to_owned()),
275                    None => DataType::Null(NOTION_TYPE_CREATED_TIME.to_owned()), 
276                }
277            }
278            NOTION_TYPE_LAST_EDITED_TIME => {
279                match element[NOTION_TYPE_LAST_EDITED_TIME].as_str() {
280                    Some(time) => DataType::LastEditedTime(time.to_owned()),
281                    None => DataType::Null(NOTION_TYPE_LAST_EDITED_TIME.to_owned()), 
282                }
283            }
284            NOTION_TYPE_LAST_EDITED_BY => {
285                match element[NOTION_TYPE_LAST_EDITED_BY][NOTION_KEYWORD_ID].as_str() {
286                    Some(user) => DataType::LastEditedBy(user.to_owned()),
287                    None => DataType::Uknown, 
288                }
289            }
290            x => {
291                println!("Unsupported: {}", x);
292                DataType::Uknown
293            }
294        }
295    }
296}
297
298#[macro_export]
299macro_rules! get_last {
300    ($element:ident) => {
301        $element.entries().last().unwrap()
302    };
303}