Optional dot syntax for anchored keys (#423)
This commit is contained in:
parent
f95a27b412
commit
7e04eb51ff
6 changed files with 36 additions and 18 deletions
|
|
@ -54,8 +54,11 @@ statement_arg_list = { statement_arg ~ ("," ~ statement_arg)* }
|
|||
|
||||
statement = { identifier ~ "(" ~ statement_arg_list? ~ ")" }
|
||||
|
||||
// Anchored Key: ?Var["key_literal"]
|
||||
anchored_key = { wildcard ~ "[" ~ literal_string ~ "]" }
|
||||
// Anchored Key: ?Var["key_literal"] or ?Var.key_identifier
|
||||
anchored_key = {
|
||||
(wildcard ~ "[" ~ literal_string ~ "]")
|
||||
| (wildcard ~ "." ~ identifier)
|
||||
}
|
||||
|
||||
// Literal Values (ordered to avoid ambiguity, e.g., string before int)
|
||||
literal_value = {
|
||||
|
|
|
|||
|
|
@ -89,11 +89,16 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_parse_anchored_key() {
|
||||
assert_parses(Rule::anchored_key, "?PodVar[\"literal_key\"]");
|
||||
assert_parses(Rule::anchored_key, "?PodVar[\"literal key\"]");
|
||||
assert_parses(Rule::anchored_key, "?PodVar.literal_key");
|
||||
assert_fails(Rule::anchored_key, "PodVar[\"key\"]"); // Needs wildcard for pod
|
||||
assert_fails(Rule::anchored_key, "?PodVar[invalid_key]"); // Key must be literal string or wildcard
|
||||
assert_fails(Rule::anchored_key, "PodVar.key"); // Needs wildcard for pod
|
||||
assert_fails(Rule::anchored_key, "?PodVar[invalid_key]"); // Key must be literal string
|
||||
assert_fails(Rule::anchored_key, "?PodVar.123"); // Key must be valid identifier
|
||||
assert_fails(Rule::anchored_key, "?PodVar[]"); // Key cannot be empty
|
||||
assert_fails(Rule::anchored_key, "?PodVar."); // Key cannot be empty
|
||||
assert_fails(Rule::anchored_key, "?PodVar[?key]"); // Key cannot be wildcard
|
||||
assert_fails(Rule::anchored_key, "?PodVar.?key"); // Key cannot be wildcard
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -214,7 +219,7 @@ mod tests {
|
|||
ValueOf(?ConstVal["min_age"], 18)
|
||||
Gt(?UserPod["age"], ?ConstVal["min_age"])
|
||||
// User must not be banned
|
||||
NotContains(?_BANNED_USERS["list"], ?UserPod["userId"])
|
||||
NotContains(?_BANNED_USERS.list, ?UserPod.userId)
|
||||
)
|
||||
|
||||
REQUEST(
|
||||
|
|
|
|||
|
|
@ -356,7 +356,14 @@ fn pest_pair_to_builder_arg(
|
|||
}
|
||||
|
||||
let key_part_pair = inner_ak_pairs.next().unwrap();
|
||||
let key_str = parse_pest_string_literal(&key_part_pair)?;
|
||||
let key_str = match key_part_pair.as_rule() {
|
||||
Rule::literal_string => parse_pest_string_literal(&key_part_pair)?,
|
||||
Rule::identifier => key_part_pair.as_str().to_string(),
|
||||
_ => unreachable!(
|
||||
"unknown key type in anchored key: {:?}",
|
||||
key_part_pair.as_rule()
|
||||
),
|
||||
};
|
||||
Ok(BuilderArg::Key(root_wc_str.to_string(), key_str))
|
||||
}
|
||||
_ => unreachable!("Unexpected rule: {:?}", arg_content_pair.as_rule()),
|
||||
|
|
@ -1065,7 +1072,7 @@ mod processor_tests {
|
|||
|
||||
#[test]
|
||||
fn test_fp_only_request() -> Result<(), ProcessorError> {
|
||||
let input = "REQUEST( Equal(?A[\"k\"],?B[\"k\"]) )"; // Escaped quotes
|
||||
let input = "REQUEST( Equal(?A[\"k\"],?B.k) )"; // Escaped quotes
|
||||
let pairs = get_document_content_pairs(input)?;
|
||||
let params = Params::default();
|
||||
let mut ctx = ProcessingContext::new(¶ms);
|
||||
|
|
@ -1082,7 +1089,7 @@ mod processor_tests {
|
|||
|
||||
#[test]
|
||||
fn test_fp_simple_predicate() -> Result<(), ProcessorError> {
|
||||
let input = "my_pred(A, B) = AND( Equal(?A[\"k\"],?B[\"k\"]) )"; // Escaped quotes
|
||||
let input = "my_pred(A, B) = AND( Equal(?A[\"k\"],?B.k) )"; // Escaped quotes
|
||||
let pairs = get_document_content_pairs(input)?;
|
||||
let params = Params::default();
|
||||
let mut ctx = ProcessingContext::new(¶ms);
|
||||
|
|
@ -1104,7 +1111,7 @@ mod processor_tests {
|
|||
#[test]
|
||||
fn test_fp_multiple_predicates() -> Result<(), ProcessorError> {
|
||||
let input = r#"
|
||||
pred1(X) = AND( Equal(?X["k"],?X["k"]) )
|
||||
pred1(X) = AND( Equal(?X["k"],?X.k) )
|
||||
pred2(Y, Z) = OR( Equal(?Y["v"], 123) )
|
||||
"#;
|
||||
let pairs = get_document_content_pairs(input)?;
|
||||
|
|
@ -1253,7 +1260,7 @@ mod processor_tests {
|
|||
// Native predicate names are case-sensitive
|
||||
let input = r#"
|
||||
REQUEST(
|
||||
EQUAL(?A["b"], ?C["d"])
|
||||
EQUAL(?A["b"], ?C.d)
|
||||
)
|
||||
"#;
|
||||
let pairs = get_document_content_pairs(input)?;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue