Skip to content

Commit b1cc167

Browse files
authored
Merge pull request #290 from supabase/or/null-literals
bugfix: null literals
2 parents 378c2b1 + 15c5a5d commit b1cc167

12 files changed

+614
-208
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "pg_graphql"
3-
version = "1.0.1"
3+
version = "1.0.2"
44
edition = "2021"
55

66
[lib]

src/builder.rs

Lines changed: 94 additions & 83 deletions
Large diffs are not rendered by default.

src/gson.rs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
gson:Value is roughly a mirror of serde_json::Value
3+
with added support for the concept of "Absent" so we
4+
can differentiate between Null literals and values that
5+
were not provided by the user.
6+
*/
7+
use serde_json;
8+
use std::collections::HashMap;
9+
10+
#[derive(Clone, Debug, PartialEq)]
11+
pub enum Value {
12+
Absent,
13+
Null,
14+
Number(Number),
15+
String(String),
16+
Boolean(bool),
17+
Array(Vec<Value>),
18+
Object(HashMap<String, Value>),
19+
}
20+
21+
#[derive(Clone, Debug, PartialEq)]
22+
pub enum Number {
23+
Integer(i64),
24+
Float(f64),
25+
}
26+
27+
pub fn json_to_gson(val: &serde_json::Value) -> Result<Value, String> {
28+
use serde_json::Value as JsonValue;
29+
30+
let v = match val {
31+
JsonValue::Null => Value::Null,
32+
JsonValue::Bool(x) => Value::Boolean(x.to_owned()),
33+
JsonValue::String(x) => Value::String(x.to_owned()),
34+
JsonValue::Array(x) => {
35+
let mut arr = vec![];
36+
for jelem in x {
37+
let gelem = json_to_gson(jelem)?;
38+
arr.push(gelem);
39+
}
40+
Value::Array(arr)
41+
}
42+
JsonValue::Number(x) => {
43+
let val: Option<i64> = x.as_i64();
44+
match val {
45+
Some(num) => {
46+
let i_val = Number::Integer(num);
47+
Value::Number(i_val)
48+
}
49+
None => {
50+
let f_val: f64 = x
51+
.as_f64()
52+
.ok_or("Failed to handle numeric user input".to_string())?;
53+
Value::Number(Number::Float(f_val))
54+
}
55+
}
56+
}
57+
JsonValue::Object(kv) => {
58+
let mut hmap = HashMap::new();
59+
for (key, v) in kv.iter() {
60+
let gson_val = json_to_gson(v)?;
61+
hmap.insert(key.to_owned(), gson_val);
62+
}
63+
Value::Object(hmap)
64+
}
65+
};
66+
Ok(v)
67+
}
68+
69+
pub fn gson_to_json(val: &Value) -> Result<serde_json::Value, String> {
70+
use serde_json::Value as JsonValue;
71+
72+
let v = match val {
73+
Value::Absent => {
74+
return Err("Encounterd `Absent` value while transforming between GraphQL intermediate object notation and JSON".to_string())
75+
},
76+
Value::Null => JsonValue::Null,
77+
Value::Boolean(x) => JsonValue::Bool(x.to_owned()),
78+
Value::String(x) => JsonValue::String(x.to_owned()),
79+
Value::Array(x) => {
80+
let mut arr = vec![];
81+
for gelem in x {
82+
let jelem = gson_to_json(gelem)?;
83+
arr.push(jelem);
84+
}
85+
JsonValue::Array(arr)
86+
}
87+
Value::Number(x) => match x {
88+
Number::Integer(y) => serde_json::json!(y),
89+
Number::Float(y) => serde_json::json!(y),
90+
},
91+
Value::Object(kv) => {
92+
let mut hmap = serde_json::Map::new();
93+
for (key, v) in kv.iter() {
94+
let json_val = gson_to_json(v)?;
95+
hmap.insert(key.to_owned(), json_val);
96+
}
97+
JsonValue::Object(hmap)
98+
}
99+
};
100+
Ok(v)
101+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use serde_json::json;
77

88
mod builder;
99
mod graphql;
10+
mod gson;
1011
mod omit;
1112
mod parser_util;
1213
mod resolve;

0 commit comments

Comments
 (0)