v_onto/
json2individual.rs

1use crate::datatype::{DataType, Lang};
2use crate::individual::Individual;
3use serde_json::value::Value as JSONValue;
4use serde_json::Map;
5
6pub fn parse_json_to_individual(src: &JSONValue, dest: &mut Individual) -> bool {
7    let mut res = true;
8
9    if let Some(props) = src.as_object() {
10        for (key, value) in props.iter() {
11            if key == "@" {
12                if let Some(id) = value.as_str() {
13                    dest.set_id(id);
14                } else {
15                    error!("json->individual: fail get id");
16                    res = false;
17                }
18            } else if let Some(values) = value.as_array() {
19                if !json_to_predicate(key, values, dest) {
20                    res = false;
21                }
22            } else {
23                error!("json->individual: predicate [{}] must contain an array of values", key);
24                res = false;
25            }
26        }
27    }
28
29    res
30}
31
32fn get_datatype_from_json(val: Option<&JSONValue>) -> Result<DataType, String> {
33    if val.is_none() {
34        return Err("not content field type".to_owned());
35    }
36
37    let tp = val.unwrap();
38    if tp.is_string() {
39        if let Some(v) = tp.as_str() {
40            if let Some(d) = DataType::new_from_str(v) {
41                return Ok(d);
42            }
43        }
44    } else if tp.is_u64() {
45        if let Some(v) = tp.as_u64() {
46            if let Some(d) = DataType::new_from_u64(v) {
47                return Ok(d);
48            }
49        }
50    } else {
51        return Err("expected string or integer for value of field [type]".to_owned());
52    }
53
54    Err("invalid value of field [type]".to_owned())
55}
56
57fn add_string(v: &Map<String, JSONValue>, vdata: &JSONValue, predicate: &str, dest: &mut Individual) {
58    if let Some(s) = vdata.as_str() {
59        let lang = if let Some(v) = v.get("lang") {
60            if v.is_string() {
61                Lang::new_from_str(v.as_str().unwrap_or_default().to_lowercase().as_str())
62            } else if v.is_number() {
63                Lang::new_from_i64(v.as_i64().unwrap_or_default())
64            } else {
65                Lang::NONE
66            }
67        } else {
68            Lang::NONE
69        };
70
71        dest.add_string(predicate, s, lang);
72    }
73}
74
75fn json_to_predicate(predicate: &str, values: &[JSONValue], dest: &mut Individual) -> bool {
76    let mut res = true;
77    for val in values {
78        if let Some(v) = val.as_object() {
79            let vdata = v.get("data");
80            if vdata.is_none() {
81                error!("json->individual: predicate [{}], value must contain [data]", predicate);
82                res = false;
83                continue;
84            }
85            let ptype = get_datatype_from_json(v.get("type"));
86            if ptype.is_err() {
87                error!("json->individual: predicate [{}], invalid value", predicate);
88                res = false;
89                continue;
90            }
91            let vdata = vdata.unwrap();
92
93            match ptype.unwrap() {
94                DataType::Uri => {
95                    if let Some(v) = vdata.as_str() {
96                        dest.add_uri(predicate, v);
97                    }
98                }
99                DataType::String => add_string(v, vdata, predicate, dest),
100
101                DataType::Integer => {
102                    if let Some(v) = vdata.as_i64() {
103                        dest.add_integer(predicate, v);
104                    }
105                }
106                DataType::Datetime => {
107                    if vdata.is_number() {
108                        if let Some(v) = vdata.as_i64() {
109                            dest.add_datetime(predicate, v);
110                        }
111                    } else if vdata.is_string() {
112                        if let Some(v) = vdata.as_str() {
113                            dest.add_datetime_from_str(predicate, v);
114                        }
115                    }
116                }
117                DataType::Decimal => {
118                    if vdata.is_f64() {
119                        if let Some(v) = vdata.as_f64() {
120                            dest.add_decimal_from_f64(predicate, v);
121                        }
122                    } else if vdata.is_number() {
123                        if let Some(v) = vdata.as_i64() {
124                            dest.add_decimal_from_i64(predicate, v);
125                        }
126                    } else if vdata.is_string() {
127                        if let Some(v) = vdata.as_str() {
128                            dest.add_decimal_from_str(predicate, v);
129                        }
130                    }
131                }
132                DataType::Boolean => {
133                    if let Some(v) = vdata.as_bool() {
134                        dest.add_bool(predicate, v);
135                    }
136                }
137                DataType::Binary => {
138                    if let Some(v) = vdata.as_str() {
139                        dest.add_binary(predicate, v.as_bytes().to_vec());
140                    }
141                }
142            }
143        } else {
144            error!("json->individual: value for predicate [{}] must contain map", predicate);
145            res = false;
146        }
147    }
148
149    res
150}