cozo_ce/data/
json.rs

1/*
2 * Copyright 2022, The Cozo Project Authors.
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
5 * If a copy of the MPL was not distributed with this file,
6 * You can obtain one at https://mozilla.org/MPL/2.0/.
7 */
8
9use base64::engine::general_purpose::STANDARD;
10use base64::Engine;
11use serde_json::json;
12pub(crate) use serde_json::Value as JsonValue;
13
14use crate::data::value::{DataValue, Num, Vector};
15use crate::JsonData;
16
17impl From<JsonValue> for DataValue {
18    fn from(v: JsonValue) -> Self {
19        match v {
20            JsonValue::Null => DataValue::Null,
21            JsonValue::Bool(b) => DataValue::Bool(b),
22            JsonValue::Number(n) => match n.as_i64() {
23                Some(i) => DataValue::from(i),
24                None => match n.as_f64() {
25                    Some(f) => DataValue::from(f),
26                    None => DataValue::from(n.to_string()),
27                },
28            },
29            JsonValue::String(s) => DataValue::from(s),
30            JsonValue::Array(arr) => DataValue::List(arr.iter().map(DataValue::from).collect()),
31            JsonValue::Object(d) => DataValue::Json(JsonData(JsonValue::Object(d))),
32        }
33    }
34}
35
36impl<'a> From<&'a JsonValue> for DataValue {
37    fn from(v: &'a JsonValue) -> Self {
38        match v {
39            JsonValue::Null => DataValue::Null,
40            JsonValue::Bool(b) => DataValue::Bool(*b),
41            JsonValue::Number(n) => match n.as_i64() {
42                Some(i) => DataValue::from(i),
43                None => match n.as_f64() {
44                    Some(f) => DataValue::from(f),
45                    None => DataValue::from(n.to_string()),
46                },
47            },
48            JsonValue::String(s) => DataValue::Str(s.into()),
49            JsonValue::Array(arr) => DataValue::List(arr.iter().map(DataValue::from).collect()),
50            JsonValue::Object(d) => DataValue::Json(JsonData(JsonValue::Object(d.clone()))),
51        }
52    }
53}
54
55impl From<DataValue> for JsonValue {
56    fn from(v: DataValue) -> Self {
57        match v {
58            DataValue::Null => JsonValue::Null,
59            DataValue::Bool(b) => JsonValue::Bool(b),
60            DataValue::Num(Num::Int(i)) => JsonValue::Number(i.into()),
61            DataValue::Num(Num::Float(f)) => {
62                if f.is_finite() {
63                    json!(f)
64                } else if f.is_nan() {
65                    json!(())
66                } else if f.is_infinite() {
67                    if f.is_sign_negative() {
68                        json!("NEGATIVE_INFINITY")
69                    } else {
70                        json!("INFINITY")
71                    }
72                } else {
73                    unreachable!()
74                }
75            }
76            DataValue::Str(t) => JsonValue::String(t.into()),
77            DataValue::Bytes(bytes) => JsonValue::String(STANDARD.encode(bytes)),
78            DataValue::List(l) => {
79                JsonValue::Array(l.iter().map(|v| JsonValue::from(v.clone())).collect())
80            }
81            DataValue::Bot => panic!("found bottom"),
82            DataValue::Set(l) => {
83                JsonValue::Array(l.iter().map(|v| JsonValue::from(v.clone())).collect())
84            }
85            DataValue::Regex(r) => {
86                json!(r.0.as_str())
87            }
88            DataValue::Uuid(u) => {
89                json!(u.0)
90            }
91            DataValue::Vec(arr) => match arr {
92                Vector::F32(a) => json!(a.as_slice().unwrap()),
93                Vector::F64(a) => json!(a.as_slice().unwrap()),
94            },
95            DataValue::Validity(v) => {
96                json!([v.timestamp.0, v.is_assert])
97            }
98            DataValue::Json(j) => j.0,
99        }
100    }
101}