Skip to content

Commit

Permalink
Merge pull request #290 from supabase/or/null-literals
Browse files Browse the repository at this point in the history
bugfix: null literals
  • Loading branch information
olirice authored Dec 16, 2022
2 parents 378c2b1 + 15c5a5d commit b1cc167
Show file tree
Hide file tree
Showing 12 changed files with 614 additions and 208 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pg_graphql"
version = "1.0.1"
version = "1.0.2"
edition = "2021"

[lib]
Expand Down
177 changes: 94 additions & 83 deletions src/builder.rs

Large diffs are not rendered by default.

101 changes: 101 additions & 0 deletions src/gson.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
gson:Value is roughly a mirror of serde_json::Value
with added support for the concept of "Absent" so we
can differentiate between Null literals and values that
were not provided by the user.
*/
use serde_json;
use std::collections::HashMap;

#[derive(Clone, Debug, PartialEq)]
pub enum Value {
Absent,
Null,
Number(Number),
String(String),
Boolean(bool),
Array(Vec<Value>),
Object(HashMap<String, Value>),
}

#[derive(Clone, Debug, PartialEq)]
pub enum Number {
Integer(i64),
Float(f64),
}

pub fn json_to_gson(val: &serde_json::Value) -> Result<Value, String> {
use serde_json::Value as JsonValue;

let v = match val {
JsonValue::Null => Value::Null,
JsonValue::Bool(x) => Value::Boolean(x.to_owned()),
JsonValue::String(x) => Value::String(x.to_owned()),
JsonValue::Array(x) => {
let mut arr = vec![];
for jelem in x {
let gelem = json_to_gson(jelem)?;
arr.push(gelem);
}
Value::Array(arr)
}
JsonValue::Number(x) => {
let val: Option<i64> = x.as_i64();
match val {
Some(num) => {
let i_val = Number::Integer(num);
Value::Number(i_val)
}
None => {
let f_val: f64 = x
.as_f64()
.ok_or("Failed to handle numeric user input".to_string())?;
Value::Number(Number::Float(f_val))
}
}
}
JsonValue::Object(kv) => {
let mut hmap = HashMap::new();
for (key, v) in kv.iter() {
let gson_val = json_to_gson(v)?;
hmap.insert(key.to_owned(), gson_val);
}
Value::Object(hmap)
}
};
Ok(v)
}

pub fn gson_to_json(val: &Value) -> Result<serde_json::Value, String> {
use serde_json::Value as JsonValue;

let v = match val {
Value::Absent => {
return Err("Encounterd `Absent` value while transforming between GraphQL intermediate object notation and JSON".to_string())
},
Value::Null => JsonValue::Null,
Value::Boolean(x) => JsonValue::Bool(x.to_owned()),
Value::String(x) => JsonValue::String(x.to_owned()),
Value::Array(x) => {
let mut arr = vec![];
for gelem in x {
let jelem = gson_to_json(gelem)?;
arr.push(jelem);
}
JsonValue::Array(arr)
}
Value::Number(x) => match x {
Number::Integer(y) => serde_json::json!(y),
Number::Float(y) => serde_json::json!(y),
},
Value::Object(kv) => {
let mut hmap = serde_json::Map::new();
for (key, v) in kv.iter() {
let json_val = gson_to_json(v)?;
hmap.insert(key.to_owned(), json_val);
}
JsonValue::Object(hmap)
}
};
Ok(v)
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use serde_json::json;

mod builder;
mod graphql;
mod gson;
mod omit;
mod parser_util;
mod resolve;
Expand Down
Loading

0 comments on commit b1cc167

Please sign in to comment.