pub(crate) mod parser;
pub(crate) mod serializer;
pub(crate) mod values;
pub(crate) mod verbs;
#[macro_use]
extern crate pest_derive;
pub type ParseError = pest::error::Error<parser::Rule>;
pub fn serialize_fql(query: impl AsRef<str>) -> Result<String, ParseError> {
let ast = parser::parse_expr(query.as_ref())?;
Ok(serializer::serialize_expr(&ast))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_and_serialize_call_string() {
let json = serialize_fql(r#"Call("fn")"#).unwrap();
let expected = r#"{"call":"fn","arguments":[]}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_call_function() {
let json = serialize_fql(r#"Call(Function("fn"))"#).unwrap();
let expected = r#"{"call":{"function":"fn"},"arguments":[]}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_call_1arg() {
let json = serialize_fql(r#"Call("fn", 1)"#).unwrap();
let expected = r#"{"call":"fn","arguments":[1]}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_call_2args() {
let json = serialize_fql(r#"Call("fn", 1, 2)"#).unwrap();
let expected = r#"{"call":"fn","arguments":[1,2]}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_concat() {
let json = serialize_fql(r#"Concat(["a", "b"])"#).unwrap();
let expected = r#"{"concat":["a","b"]}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_concat_with_separator() {
let json = serialize_fql(r#"Concat(["a", "b"], " ")"#).unwrap();
let expected = r#"{"concat":["a","b"],"separator":" "}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_filter() {
let json = serialize_fql(r#"Filter(["a","b"],Lambda([],true))"#).unwrap();
let expected = r#"{"collection":["a","b"],"filter":{"lambda":[],"expr":true}}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_foreach() {
let json = serialize_fql(r#"Foreach(["a","b"],Lambda([],true))"#).unwrap();
let expected = r#"{"collection":["a","b"],"foreach":{"lambda":[],"expr":true}}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_lambda_with_string() {
let json = serialize_fql(r#"Lambda("x", Var("x"))"#).unwrap();
let expected = r#"{"lambda":"x","expr":{"var":"x"}}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_lambda_with_empty_string() {
let json = serialize_fql(r#"Lambda("", true)"#).unwrap();
let expected = r#"{"lambda":"","expr":true}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_lambda_with_array() {
let json = serialize_fql(r#"Lambda(["x"], Var("x"))"#).unwrap();
let expected = r#"{"lambda":["x"],"expr":{"var":"x"}}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_lambda_with_empty_array() {
let json = serialize_fql(r#"Lambda([], true)"#).unwrap();
let expected = r#"{"lambda":[],"expr":true}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_let() {
let json = serialize_fql(
r#"Let(
{
"value": true
},
Var("value")
)"#,
)
.unwrap();
let expected = r#"{"let":{"value":true},"in":{"var":"value"}}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_map() {
let json = serialize_fql(r#"Map(["a","b"],Lambda([],true))"#).unwrap();
let expected = r#"{"collection":["a","b"],"map":{"lambda":[],"expr":true}}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_match_index() {
let json = serialize_fql(r#"Match(Index("all_things"))"#).unwrap();
let expected = r#"{"match":{"index":"all_things"},"terms":[]}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_match_string() {
let json = serialize_fql(r#"Match("all_things")"#).unwrap();
let expected = r#"{"match":"all_things","terms":[]}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_match_with_args_array() {
let json = serialize_fql(r#"Match("things_by_name", ["Alice"])"#).unwrap();
let expected = r#"{"match":"things_by_name","terms":["Alice"]}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_match_with_args_value_string() {
let json = serialize_fql(r#"Match("things_by_name", "Alice")"#).unwrap();
let expected = r#"{"match":"things_by_name","terms":"Alice"}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_match_with_args_value_expr() {
let json = serialize_fql(r#"Match("things_by_date", Date("2022-01-01"))"#).unwrap();
let expected = r#"{"match":"things_by_date","terms":{"date":"2022-01-01"}}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_merge() {
let json = serialize_fql(
r#"Merge(
{"c":"Compare","d":"Difference"},
{"c":"Contrast","d":"Delta"}
)"#,
)
.unwrap();
let mut expected = String::from(
r#"{
"merge":{"object":{"c":"Compare","d":"Difference"}},
"with":{"object":{"c":"Contrast","d":"Delta"}}
}"#,
);
expected.retain(|c| !c.is_whitespace());
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_merge_with_lambda() {
let json = serialize_fql(
r#"Merge(
{"c":"Compare","d":"Difference"},
{"c":"Contrast","d":"Delta"},
Lambda(["key","a","b"],If(Equals(Var("key"),"c"),Var("a"),Var("b")))
)"#,
)
.unwrap();
let mut expected = String::from(
r#"{
"merge":{"object":{"c":"Compare","d":"Difference"}},
"with":{"object":{"c":"Contrast","d":"Delta"}},
"lambda":{
"lambda":["key","a","b"],
"expr":{"if":{"equals":[{"var":"key"},"c"]},"then":{"var":"a"},"else":{"var":"b"}}
}
}"#,
);
expected.retain(|c| !c.is_whitespace());
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_object() {
let json = serialize_fql(
r#"{
"value": true
}"#,
)
.unwrap();
let expected = r#"{"object":{"value":true}}"#;
assert_eq!(json, expected);
}
#[test]
fn parse_and_serialize_paginate() {
let json = serialize_fql(
r#"Paginate(
Collections(),
{ "size": 1 }
)"#,
)
.unwrap();
let expected = r#"{"paginate":{"collections":null},"size":1}"#;
assert_eq!(json, expected);
}
}