Skip to content

Instantly share code, notes, and snippets.

@abhayarawal
Last active March 23, 2020 10:13
Show Gist options
  • Save abhayarawal/a6a0504f14328e575d007e1afcbef400 to your computer and use it in GitHub Desktop.
Save abhayarawal/a6a0504f14328e575d007e1afcbef400 to your computer and use it in GitHub Desktop.
Rust json! macro
use std::collections::HashMap;
#[derive(Debug, PartialEq, Clone)]
enum Json {
Null,
Boolean(bool),
Number(f64),
String(String),
Array(Vec<Json>),
Object(Box<HashMap<String, Json>>),
}
impl From<String> for Json {
fn from(s: String) -> Json {
Json::String(s)
}
}
impl<'a> From<&'a str> for Json {
fn from(s: &'a str) -> Json {
Json::String(s.to_string())
}
}
macro_rules! impl_num_json {
( $( $t:ident )+ ) => {
$(
impl From<$t> for Json {
fn from(n: $t) -> Json {
Json::Number(n as f64)
}
}
)+
}
}
impl_num_json!(u8 i8 u16 i16 u32 i32 u64 i64 usize isize f32 f64);
macro_rules! json {
( null ) => { Json::Null };
( true ) => { Json::Boolean(true) };
( false ) => { Json::Boolean(false) };
([$( $element:tt ),* ]) => {
Json::Array(vec![$( json!($element) ), *])
};
({ $( $k:tt : $v:tt ),* }) => {
Json::Object(Box::new(
vec![
$( ($k.to_string(), json!($v)) ),*
].into_iter().collect()
))
};
( $other:tt ) => {
Json::from($other)
}
}
fn main() {
let js1 = Json::Array(vec![
Json::Boolean(true),
Json::Boolean(false),
Json::String("hello".to_string()),
Json::Object(Box::new(
vec![(
"a".to_string(),
Json::Object(Box::new(
vec![(
"b".to_string(),
Json::Array(vec![Json::Null, Json::Number(90.09 as f64)]),
)].into_iter().collect(),
)),
)].into_iter().collect(),
)),
]);
println!("{:?}", js1);
let js2 = json!([
true,
false,
"hello",
{ "a": { "b": [null, 90.09] } }
]);
println!("{:?}", js2);
}
#![allow(dead_code, unused)]
use dgraph::{make_dgraph, Dgraph, Request};
use serde_derive::{Deserialize, Serialize};
use serde_json::Value;
fn user_type() -> String {
"User".to_string()
}
#[derive(Debug, Default, Serialize, Deserialize)]
struct User {
uid: Option<String>,
name: String,
age: Option<u8>,
friends: Option<Vec<User>>,
#[serde(rename = "dgraph.type")]
#[serde(default = "user_type")]
dgraph_type: String,
}
fn drop_all(dg: &Dgraph) {
let op_clean = dgraph::Operation {
drop_all: true,
..Default::default()
};
dg.alter(&op_clean).expect("drop schema");
}
fn set_schema(dg: &Dgraph) {
let op_schema = dgraph::Operation {
schema: r#"
type User {
name
age
friends
}
name: string @index(exact, term) .
age: int .
friends: [uid] @reverse .
"#
.to_string(),
..Default::default()
};
dg.alter(&op_schema).expect("set schema");
}
fn insert(dg: &Dgraph, user: User) -> String {
let mut mutation = dgraph::Mutation::default();
mutation.set_set_json(serde_json::to_vec(&user).expect("invalid json"));
let mut txn = dg.new_txn();
let assigned = txn.mutate(mutation).expect("failed to create data");
txn.commit().expect("failed to commit mutation");
let mut uid: String = "".to_string();
for (_, v) in assigned.uids.iter() {
uid = v.to_string();
}
uid
}
macro_rules! jin {
[ $j:expr; $( $e:expr ),+ ] => (
(|| {
let res = $j$(.get($e)?)+;
Some(res)
})();
);
}
fn main() {
let dg = make_dgraph!(dgraph::new_dgraph_client("localhost:9080"));
// set_schema(&dg);
let query = r#"
{
query(func: eq(name, "Marcella")) {
uid
name
age
friends (orderasc: age) @filter(le(age, "30")) @facets(related) {
uid
name
age
}
~friends {
uid
name
age
}
}
}
"#
.to_string();
let resp = dg.new_readonly_txn().query(query).expect("query");
let j: Value = serde_json::from_slice(&resp.json).expect("parsing");
let p = jin![j; "query", 0, "friends", 0, "name"];
println!(
"{:?}",
match p {
Some(v) => v,
None => &Value::Null,
}
);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn drop_db() {
let dg = make_dgraph!(dgraph::new_dgraph_client("localhost:9080"));
// drop_all(&dg);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment