Support SELF keyword in Podlang parser (#368)

* Support SELF keyword in Podlang parser

* Add pretty-printing for SELF
This commit is contained in:
Rob Knight 2025-07-30 01:35:48 +01:00 committed by GitHub
parent 0606a4098b
commit c7b39f21f0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 39 additions and 5 deletions

View file

@ -68,7 +68,8 @@ literal_value = {
literal_raw |
literal_pod_id |
literal_string |
literal_int
literal_int |
self_keyword
}
// Primitive literal types

View file

@ -34,7 +34,7 @@ mod tests {
middleware::{
hash_str, CustomPredicate, CustomPredicateBatch, CustomPredicateRef, Key,
NativePredicate, Params, PodId, PodType, Predicate, RawValue, StatementTmpl,
StatementTmplArg, Value, Wildcard, KEY_SIGNER, KEY_TYPE,
StatementTmplArg, Value, Wildcard, KEY_SIGNER, KEY_TYPE, SELF,
},
};
@ -877,6 +877,7 @@ mod tests {
Equal(?E["int"], {})
Equal(?F["bool"], {})
Equal(?G["sk"], {})
Equal(?H["self"], SELF)
)
"#,
Value::from(pk).to_podlang_string(),
@ -895,6 +896,8 @@ mod tests {
Equal(?D["string"], "hello")
Equal(?E["int"], 123)
Equal(?F["bool"], true)
Equal(?G["sk"], SecretKey(random_secret_key_base_64))
Equal(?H["self"], SELF)
)
*/
@ -902,8 +905,6 @@ mod tests {
let processed = parse(&input, &params, &[])?;
let request_templates = processed.request_templates;
assert_eq!(request_templates.len(), 7);
let expected_templates = vec![
StatementTmpl {
pred: Predicate::Native(NativePredicate::Equal),
@ -933,6 +934,10 @@ mod tests {
pred: Predicate::Native(NativePredicate::Equal),
args: vec![sta_ak(("G", 6), "sk"), sta_lit(Value::from(sk))],
},
StatementTmpl {
pred: Predicate::Native(NativePredicate::Equal),
args: vec![sta_ak(("H", 7), "self"), sta_lit(Value::from(SELF))],
},
];
assert_eq!(request_templates, expected_templates);

View file

@ -507,6 +507,16 @@ mod tests {
assert_round_trip(&input);
}
#[test]
fn test_round_trip_self() {
let input = r#"
self_test(Pod) = AND(
Equal(?Pod["self"], SELF)
)
"#;
assert_round_trip(input);
}
#[test]
fn test_pretty_print_demonstration() {
let input = r#"

View file

@ -817,6 +817,7 @@ fn process_literal_value(
})?;
Ok(Value::from(secret_key))
}
Rule::self_keyword => Ok(Value::from(middleware::SELF)),
_ => unreachable!("Unexpected rule: {:?}", inner_lit.as_rule()),
}
}

View file

@ -266,8 +266,12 @@ impl fmt::Display for TypedValue {
TypedValue::PublicKey(p) => write!(f, "PublicKey({})", p),
TypedValue::SecretKey(p) => write!(f, "SecretKey({})", p),
TypedValue::PodId(p) => {
if *p == SELF {
write!(f, "SELF")
} else {
write!(f, "0x{}", p.0.encode_hex::<String>())
}
}
TypedValue::Raw(r) => {
write!(f, "Raw(0x{})", r.encode_hex::<String>())
}
@ -341,6 +345,18 @@ impl JsonSchema for TypedValue {
..Default::default()
};
let pod_id_schema = schemars::schema::SchemaObject {
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Object))),
object: Some(Box::new(schemars::schema::ObjectValidation {
properties: [("PodId".to_string(), gen.subschema_for::<PodId>())]
.into_iter()
.collect(),
required: ["PodId".to_string()].into_iter().collect(),
..Default::default()
})),
..Default::default()
};
let public_key_schema = schemars::schema::SchemaObject {
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Object))),
object: Some(Box::new(schemars::schema::ObjectValidation {
@ -377,6 +393,7 @@ impl JsonSchema for TypedValue {
Schema::Object(SchemaObject {
subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
any_of: Some(vec![
Schema::Object(pod_id_schema),
Schema::Object(int_schema),
Schema::Object(raw_schema),
Schema::Object(public_key_schema),