notion_into_sqlite/
json_util.rs1use serde_json::Value;
2
3#[derive(Debug)]
4pub enum JsonKey<'a> {
5 String(&'a str),
6 Index(usize),
7}
8impl<'a> From<&'a str> for JsonKey<'a> {
9 fn from(s: &'a str) -> Self {
10 JsonKey::String(s)
11 }
12}
13impl From<usize> for JsonKey<'_> {
14 fn from(i: usize) -> Self {
15 JsonKey::Index(i)
16 }
17}
18
19pub fn dig_json<'a>(source: &'a Value, keys: &[JsonKey]) -> Option<&'a Value> {
20 let mut value = source;
21 for key in keys {
22 value = match *key {
23 JsonKey::String(k) => value.as_object()?.get(k)?,
24 JsonKey::Index(index) => value.as_array()?.get(index)?,
25 }
26 }
27 Some(value)
28}
29
30#[cfg(test)]
31mod tests {
32 use super::*;
33
34 #[test]
35 fn test_dig_json() {
36 let data = serde_json::from_str::<Value>("{}").unwrap();
37 let keys: Vec<JsonKey> = vec!["foo".into(), "foo".into(), 1.into()];
38 assert!(dig_json(&data, &keys).is_none());
39
40 let data = serde_json::from_str::<Value>(
41 r#"{
42 "foo": {
43 "bar": [
44 {
45 "id": "xxx"
46 }
47 ]
48 }
49 }"#,
50 )
51 .unwrap();
52 let keys: Vec<JsonKey> = vec!["foo".into(), "bar".into(), 0.into(), "id".into()];
53 assert_eq!(dig_json(&data, &keys).unwrap(), "xxx");
54 }
55}