use super::values::*;
use super::verbs::*;
pub fn serialize_expr(val: &FQLValue) -> String {
use FQLValue::*;
match val {
Object(o) => serialize_object(o),
Array(a) => serialize_array(a),
String(s) => format!("\"{}\"", s),
Number(n) => format!("{}", n),
Boolean(b) => format!("{}", b),
Null => format!("null"),
NiladicVerb(v) => serialize_niladic_verb(v),
MonadicVerb(v) => serialize_monadic_verb(v),
DyadicVerb(v) => serialize_dyadic_verb(v),
TriadicVerb(v) => serialize_triadic_verb(v),
QuadraticVerb(v) => serialize_quadratic_verb(v),
VariadicVerb(v) => serialize_variadic_verb(v),
}
}
fn serialize_object(o: &Vec<(&str, FQLValue)>) -> String {
let contents: Vec<_> = o
.iter()
.map(|(name, value)| format!("\"{}\":{}", name, serialize_expr(value)))
.collect();
format!(r#"{{"object":{{{}}}}}"#, contents.join(","))
}
fn serialize_array(a: &Vec<FQLValue>) -> String {
let contents: Vec<_> = a.iter().map(serialize_expr).collect();
format!("[{}]", contents.join(","))
}
fn serialize_niladic_verb(v: &NiladicVerb) -> String {
format!(r#"{{"{}":null}}"#, translate_verb(&v.verb))
}
fn serialize_monadic_verb(v: &MonadicVerb) -> String {
format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
)
}
fn serialize_dyadic_verb(v: &DyadicVerb) -> String {
match v.verb {
"Append" => format_dyad(v, "collection"),
"At" => format_dyad(v, "expr"),
"Casefold" => format_dyad(v, "normalizer"),
"ContainsField" => format_dyad(v, "in"),
"ContainsPath" => format_dyad(v, "in"),
"ContainsStr" => format_dyad(v, "search"),
"ContainsStrRegex" => format_dyad(v, "pattern"),
"ContainsValue" => format_dyad(v, "in"),
"Create" => format_dyad(v, "params"),
"Drop" => format_dyad(v, "collection"),
"EndsWith" => format_dyad(v, "search"),
"Epoch" => format_dyad(v, "unit"),
"Filter" => format!(
r#"{{"collection":{},"filter":{}}}"#,
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
"Foreach" => format!(
r#"{{"collection":{},"foreach":{}}}"#,
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
"Hypot" => format_dyad(v, "b"),
"Identify" => format_dyad(v, "password"),
"Join" => format_dyad(v, "with"),
"Lambda" => format_dyad(v, "expr"),
"Let" => {
let bindings = match &v.args[0] {
FQLValue::Object(bindings) => bindings.iter()
.map(|(name, value)| format!("\"{}\":{}", name, serialize_expr(value)))
.collect::<Vec<_>>().join(","),
_ => panic!("")
};
format!(
r#"{{"let":{{{}}},"in":{}}}"#,
bindings,
serialize_expr(&v.args[1])
)
},
"Login" => format_dyad(v, "params"),
"Map" => format!(
r#"{{"collection":{},"map":{}}}"#,
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
"MoveDatabase" => format_dyad(v, "to"),
"Pow" => format_dyad(v, "exp"),
"Prepend" => format_dyad(v, "collection"),
"Ref" => format_dyad(v, "id"),
"Replace" => format_dyad(v, "params"),
"StartsWith" => format_dyad(v, "search"),
"Take" => format_dyad(v, "collection"),
"Update" => format_dyad(v, "params"),
_ => panic!("Expected a DyadicVerb"),
}
}
fn serialize_triadic_verb(v: &TriadicVerb) -> String {
match v.verb {
"If" => format!(
r#"{{"{}":{},"then":{},"else":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1]),
serialize_expr(&v.args[2]),
),
_ => panic!("Expected a TriadicVerb"),
}
}
fn serialize_quadratic_verb(v: &QuadraticVerb) -> String {
match v.verb {
"Insert" => format!(
r#"{{"{}":{},"ts":{},"action":{},"params":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1]),
serialize_expr(&v.args[2]),
serialize_expr(&v.args[2]),
),
_ => panic!("Expected a QuadraticVerb"),
}
}
fn serialize_variadic_verb(v: &VariadicVerb) -> String {
match v.verb {
"AccessProvider" => match v.args.len() {
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
2 => format!(
r#"{{"{}":{},"scope":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
_ => panic!("AccessProvider() expects one or two arguments."),
},
"AccessProviders" => match v.args.len() {
0 => format!(r#"{{"{}":null}}"#, translate_verb(&v.verb)),
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
_ => panic!("AccessProviders() expects zero or one arguments."),
},
"Call" => format!(
r#"{{"{}":{},"arguments":[{}]}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
&v.args[1..]
.iter()
.map(serialize_expr)
.collect::<Vec<_>>()
.join(","),
),
"Collection" => match v.args.len() {
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
2 => format!(
r#"{{"{}":{},"scope":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
_ => panic!("Collection() expects one or two arguments."),
},
"Collections" => match v.args.len() {
0 => format!(r#"{{"{}":null}}"#, translate_verb(&v.verb)),
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
_ => panic!("Collections() expects zero or one arguments."),
},
"Concat" => match v.args.len() {
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
2 => format!(
r#"{{"{}":{},"separator":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
_ => panic!("Concat() expects one or two arguments."),
},
"Credentials" => match v.args.len() {
0 => format!(r#"{{"{}":null}}"#, translate_verb(&v.verb)),
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
_ => panic!("Credentials() expects zero or one arguments."),
},
"Database" => match v.args.len() {
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
2 => format!(
r#"{{"{}":{},"scope":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
_ => panic!("Database() expects one or two arguments."),
},
"Databases" => match v.args.len() {
0 => format!(r#"{{"{}":null}}"#, translate_verb(&v.verb)),
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
_ => panic!("Databases() expects zero or one arguments."),
},
"Exists" => match v.args.len() {
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
2 => format!(
r#"{{"{}":{},"ts":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
_ => panic!("Exists() expects one or two arguments."),
},
"FindStr" => match v.args.len() {
2 => format!(
r#"{{"{}":{},"find":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
3 => format!(
r#"{{"{}":{},"find":{},"start":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1]),
serialize_expr(&v.args[2])
),
_ => panic!("FindStr() expects two or three arguments."),
},
"FindStrRegex" => match v.args.len() {
2 => format!(
r#"{{"{}":{},"pattern":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
3 => format!(
r#"{{"{}":{},"pattern":{},"start":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1]),
serialize_expr(&v.args[2])
),
4 => format!(
r#"{{"{}":{},"pattern":{},"start":{},"num_results":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1]),
serialize_expr(&v.args[2]),
serialize_expr(&v.args[3])
),
_ => panic!("FindStrRegex() expects between two and four arguments."),
},
"Format" => format!(
r#"{{"{}":{},"values":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
&v.args[1..]
.iter()
.map(serialize_expr)
.collect::<Vec<_>>()
.join(","),
),
"Function" => match v.args.len() {
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
2 => format!(
r#"{{"{}":{},"scope":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
_ => panic!("Function() expects one or two arguments."),
},
"Functions" => match v.args.len() {
0 => format!(r#"{{"{}":null}}"#, translate_verb(&v.verb)),
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
_ => panic!("Functions() expects zero or one arguments."),
},
"Get" => match v.args.len() {
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
2 => format!(
r#"{{"{}":{},"ts":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
_ => panic!("Get() expects one or two arguments."),
},
"Index" => match v.args.len() {
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
2 => format!(
r#"{{"{}":{},"scope":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
_ => panic!("Index() expects one or two arguments."),
},
"Indexes" => match v.args.len() {
0 => format!(r#"{{"{}":null}}"#, translate_verb(&v.verb)),
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
_ => panic!("Indexes() expects zero or one arguments."),
},
"Keys" => match v.args.len() {
0 => format!(r#"{{"{}":null}}"#, translate_verb(&v.verb)),
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
_ => panic!("Keys() expects zero or one arguments."),
},
"Match" => {
let mut args_iter = v.args.iter();
let match_set = serialize_expr(args_iter.next().unwrap());
let match_arguments = match args_iter.next() {
Some(value) => serialize_expr(value),
None => String::from("[]")
};
format!(
r#"{{"match":{},"terms":{}}}"#,
match_set,
match_arguments
)
},
"Merge" => match v.args.len() {
2 => format!(
r#"{{"{}":{},"with":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
3 => format!(
r#"{{"{}":{},"with":{},"lambda":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1]),
serialize_expr(&v.args[2])
),
_ => panic!("Merge() expects two or three arguments."),
},
"Paginate" => match v.args.len() {
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
2 => {
let paginate_args = match &v.args[1] {
FQLValue::Object(args) => args,
_ => panic!("Paginate() expects an Object as the second argument")
};
let comma_separated = paginate_args
.iter()
.map(|(key, value)| {
let value_serialized = serialize_expr(value);
format!("\"{}\":{}", key, value_serialized)
}
)
.collect::<Vec<String>>().join(",");
format!(
r#"{{"{}":{},{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
comma_separated
)
},
_ => panic!("Paginate() expects one or two arguments.")
},
"Repeat" => match v.args.len() {
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
2 => format!(
r#"{{"{}":{},"number":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
_ => panic!("Repeat() expects one or two arguments."),
},
"ReplaceStrRegex" => match v.args.len() {
3 => format!(
r#"{{"{}":{},"pattern":{},"replace":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1]),
serialize_expr(&v.args[2])
),
4 => format!(
r#"{{"{}":{},"pattern":{},"replace":{},"first":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1]),
serialize_expr(&v.args[2]),
serialize_expr(&v.args[3])
),
_ => panic!("ReplaceStrRegex() expects between two and four arguments."),
},
"Role" => match v.args.len() {
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
2 => format!(
r#"{{"{}":{},"scope":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
_ => panic!("Role() expects one or two arguments."),
},
"Roles" => match v.args.len() {
0 => format!(r#"{{"{}":null}}"#, translate_verb(&v.verb)),
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
_ => panic!("Roles() expects zero or one arguments."),
},
"Round" => match v.args.len() {
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
2 => format!(
r#"{{"{}":{},"precision":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
_ => panic!("Concat() expects one or two arguments."),
},
"Select" => match v.args.len() {
2 => format!(
r#"{{"{}":{},"from":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
3 => format!(
r#"{{"{}":{},"from":{},"default":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1]),
serialize_expr(&v.args[2])
),
_ => panic!("SubString() expects two or three arguments."),
},
"SubString" => match v.args.len() {
2 => format!(
r#"{{"{}":{},"start":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
3 => format!(
r#"{{"{}":{},"start":{},"length":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1]),
serialize_expr(&v.args[2])
),
_ => panic!("SubString() expects two or three arguments."),
},
"Tokens" => match v.args.len() {
0 => format!(r#"{{"{}":null}}"#, translate_verb(&v.verb)),
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
_ => panic!("Tokens() expects zero or one arguments."),
},
"Trunc" => match v.args.len() {
1 => format!(
r#"{{"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0])
),
2 => format!(
r#"{{"{}":{},"precision":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
serialize_expr(&v.args[1])
),
_ => panic!("Concat() expects one or two arguments."),
},
_ => format!(
r#"{{"{}":[{}]}}"#,
translate_verb(&v.verb),
v.args
.iter()
.map(serialize_expr)
.collect::<Vec<_>>()
.join(",")
),
}
}
fn format_dyad(v: &DyadicVerb, key: &str) -> String {
format!(
r#"{{"{}":{},"{}":{}}}"#,
translate_verb(&v.verb),
serialize_expr(&v.args[0]),
key,
serialize_expr(&v.args[1])
)
}
fn translate_verb(verb: &str) -> &str {
match verb {
"Abort" => "abort",
"Abs" => "abs",
"AccessProvider" => "access_provider",
"AccessProviders" => "access_providers",
"Acos" => "acos",
"Add" => "add",
"All" => "all",
"And" => "and",
"Any" => "any",
"Append" => "append",
"Asin" => "asin",
"At" => "at",
"Atan" => "atan",
"BitAnd" => "bitand",
"BitNot" => "bitnot",
"BitOr" => "bitor",
"BitXor" => "bitxor",
"Call" => "call",
"Casefold" => "casefold",
"Ceil" => "ceil",
"Collection" => "collection",
"Collections" => "collections",
"Concat" => "concat",
"ContainsField" => "contains_field",
"ContainsPath" => "contains_path",
"ContainsStr" => "containsstr",
"ContainsStrRegex" => "containsstrregex",
"ContainsValue" => "contains_value",
"Cos" => "cos",
"Cosh" => "cosh",
"Count" => "count",
"Create" => "create",
"CreateAccessProvider" => "create_access_provider",
"CreateCollection" => "create_collection",
"CreateDatabase" => "create_database",
"CreateFunction" => "create_function",
"CreateIndex" => "create_index",
"CreateKey" => "create_key",
"CreateRole" => "create_role",
"Credentials" => "credentials",
"CurrentIdentity" => "current_identity",
"CurrentToken" => "current_token",
"Database" => "database",
"Databases" => "databases",
"Date" => "date",
"DayOfMonth" => "day_of_month",
"DayOfWeek" => "day_of_week",
"DayOfYear" => "day_of_year",
"Degrees" => "degrees",
"Delete" => "delete",
"Difference" => "difference",
"Distinct" => "distinct",
"Divide" => "divide",
"Do" => "do",
"Documents" => "documents",
"Drop" => "drop",
"EndsWith" => "endswith",
"Epoch" => "epoch",
"Equals" => "equals",
"Events" => "events",
"Exists" => "exists",
"Exp" => "exp",
"Filter" => "filter",
"FindStr" => "findstr",
"FindStrRegex" => "findstrregex",
"Floor" => "floor",
"Foreach" => "foreach",
"Format" => "format",
"Function" => "function",
"Functions" => "functions",
"GT" => "gt",
"GTE" => "gte",
"Get" => "get",
"HasCurrentIdentity" => "has_current_identity",
"HasCurrentToken" => "has_current_token",
"Hour" => "hour",
"If" => "if",
"Index" => "index",
"Indexes" => "indexes",
"Intersection" => "intersection",
"IsArray" => "is_array",
"IsBoolean" => "is_boolean",
"IsBytes" => "is_bytes",
"IsCollection" => "is_collection",
"IsCredentials" => "is_credentials",
"IsDatabase" => "is_database",
"IsDate" => "is_date",
"IsDoc" => "is_doc",
"IsDouble" => "is_double",
"IsEmpty" => "is_empty",
"IsFunction" => "is_function",
"IsIndex" => "is_index",
"IsInteger" => "is_integer",
"IsKey" => "is_key",
"IsLambda" => "is_lambda",
"IsNonEmpty" => "is_nonempty",
"IsNull" => "is_null",
"IsNumber" => "is_number",
"IsObject" => "is_object",
"IsRef" => "is_ref",
"IsRole" => "is_role",
"IsSet" => "is_set",
"IsString" => "is_string",
"IsTimestamp" => "is_timestamp",
"IsToken" => "is_token",
"KeyFromSecret" => "key_from_secret",
"Keys" => "keys",
"Let" => "let",
"LT" => "lt",
"LTE" => "lte",
"LTrim" => "ltrim",
"Lambda" => "lambda",
"Length" => "length",
"Ln" => "ln",
"Log" => "log",
"Logout" => "logout",
"LowerCase" => "lowercase",
"Map" => "map",
"Match" => "match",
"Max" => "max",
"Mean" => "mean",
"Merge" => "merge",
"Min" => "min",
"Minute" => "minute",
"Modulo" => "modulo",
"Month" => "month",
"Multiply" => "multiply",
"NewId" => "new_id",
"Not" => "not",
"Now" => "now",
"Paginate" => "paginate",
"Or" => "or",
"Query" => "query",
"RTrim" => "rtrim",
"Radians" => "radians",
"RegexEscape" => "regexescape",
"Repeat" => "repeat",
"Reverse" => "reverse",
"Ref" => "ref",
"Role" => "role",
"Roles" => "roles",
"Round" => "round",
"Second" => "second",
"Select" => "select",
"Sign" => "sign",
"Sin" => "sin",
"Singleton" => "singleton",
"Sinh" => "sinh",
"Space" => "space",
"Sqrt" => "sqrt",
"SubString" => "substring",
"Subtract" => "subtract",
"Sum" => "sum",
"Tan" => "tan",
"Tanh" => "tanh",
"Time" => "time",
"TitleCase" => "titlecase",
"ToArray" => "to_array",
"ToDate" => "to_date",
"ToDouble" => "to_double",
"ToInteger" => "to_integer",
"ToMicros" => "to_micros",
"ToMillis" => "to_millis",
"ToNumber" => "to_number",
"ToObject" => "to_object",
"ToSeconds" => "to_seconds",
"ToString" => "to_string",
"ToTime" => "to_time",
"Tokens" => "tokens",
"Trim" => "trim",
"Trunc" => "trunc",
"Union" => "union",
"UpperCase" => "uppercase",
"Var" => "var",
"Year" => "year",
_ => "not_yet_implemented",
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn serialize_object() {
let o: FQLValue = FQLValue::Object(vec![
("a", FQLValue::String("b")),
("c", FQLValue::Number(1.0)),
(
"d",
FQLValue::Array(
[1.0, 2.0, 3.14159]
.iter()
.map(|n| FQLValue::Number(*n))
.collect(),
),
),
]);
let compare_string = r#"{"object":{"a":"b","c":1,"d":[1,2,3.14159]}}"#;
assert_eq!(serialize_expr(&o), compare_string);
}
#[test]
fn serialize_array() {
let a: FQLValue = FQLValue::Array(
[1.0, 2.0, 3.14159]
.iter()
.map(|n| FQLValue::Number(*n))
.collect(),
);
let compare_string = "[1,2,3.14159]";
assert_eq!(serialize_expr(&a), compare_string);
}
#[test]
fn serialize_string() {
let test_string = "This is a test string with numbers (234.042.023) and punctuation.";
let compare_string = format!("\"{}\"", test_string);
let v: FQLValue = FQLValue::String(test_string);
assert_eq!(serialize_expr(&v), compare_string);
}
#[test]
fn serialize_number() {
let v: FQLValue = FQLValue::Number(2.0);
assert_eq!(serialize_expr(&v), "2");
}
#[test]
fn serialize_boolean() {
let t: FQLValue = FQLValue::Boolean(true);
let f: FQLValue = FQLValue::Boolean(false);
assert_eq!(serialize_expr(&t), "true");
assert_eq!(serialize_expr(&f), "false");
}
#[test]
fn serialize_null() {
let n: FQLValue = FQLValue::Null;
assert_eq!(serialize_expr(&n), "null");
}
#[test]
fn serialize_niladic_verb() {
let v: NiladicVerb = NiladicVerb {
verb: "CurrentIdentity",
};
assert_eq!(
serialize_expr(&FQLValue::NiladicVerb(v)),
r#"{"current_identity":null}"#
);
}
#[test]
fn serialize_monadic_verb() {
let v: MonadicVerb = MonadicVerb {
verb: "Abs",
args: vec![FQLValue::Number(-1.0)],
};
assert_eq!(serialize_expr(&FQLValue::MonadicVerb(v)), r#"{"abs":-1}"#);
}
#[test]
fn serialize_dyadic_verb() {
let base: FQLValue = FQLValue::Array(
[1.0, 2.0, 3.0]
.iter()
.map(|n| FQLValue::Number(*n))
.collect(),
);
let elems: FQLValue = FQLValue::Array(
[4.0, 5.0, 6.0]
.iter()
.map(|n| FQLValue::Number(*n))
.collect(),
);
let v: DyadicVerb = DyadicVerb {
verb: "Append",
args: vec![elems, base],
};
assert_eq!(
serialize_expr(&FQLValue::DyadicVerb(v)),
r#"{"append":[4,5,6],"collection":[1,2,3]}"#
);
}
#[test]
fn serialize_triadic_verb() {
let v: TriadicVerb = TriadicVerb {
verb: "If",
args: vec![
FQLValue::Boolean(true),
FQLValue::Boolean(true),
FQLValue::Boolean(false),
],
};
assert_eq!(
serialize_expr(&FQLValue::TriadicVerb(v)),
r#"{"if":true,"then":true,"else":false}"#
);
}
#[test]
fn serialize_variadic_verb() {
let v: VariadicVerb = VariadicVerb {
verb: "Add",
args: vec![FQLValue::Number(1.0), FQLValue::Number(2.0)],
};
assert_eq!(
serialize_expr(&FQLValue::VariadicVerb(v)),
r#"{"add":[1,2]}"#
);
}
}