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_raw |
literal_pod_id | literal_pod_id |
literal_string | literal_string |
literal_int literal_int |
self_keyword
} }
// Primitive literal types // Primitive literal types

View file

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

View file

@ -507,6 +507,16 @@ mod tests {
assert_round_trip(&input); 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] #[test]
fn test_pretty_print_demonstration() { fn test_pretty_print_demonstration() {
let input = r#" let input = r#"

View file

@ -817,6 +817,7 @@ fn process_literal_value(
})?; })?;
Ok(Value::from(secret_key)) Ok(Value::from(secret_key))
} }
Rule::self_keyword => Ok(Value::from(middleware::SELF)),
_ => unreachable!("Unexpected rule: {:?}", inner_lit.as_rule()), _ => 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::PublicKey(p) => write!(f, "PublicKey({})", p),
TypedValue::SecretKey(p) => write!(f, "SecretKey({})", p), TypedValue::SecretKey(p) => write!(f, "SecretKey({})", p),
TypedValue::PodId(p) => { TypedValue::PodId(p) => {
if *p == SELF {
write!(f, "SELF")
} else {
write!(f, "0x{}", p.0.encode_hex::<String>()) write!(f, "0x{}", p.0.encode_hex::<String>())
} }
}
TypedValue::Raw(r) => { TypedValue::Raw(r) => {
write!(f, "Raw(0x{})", r.encode_hex::<String>()) write!(f, "Raw(0x{})", r.encode_hex::<String>())
} }
@ -341,6 +345,18 @@ impl JsonSchema for TypedValue {
..Default::default() ..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 { let public_key_schema = schemars::schema::SchemaObject {
instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Object))), instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Object))),
object: Some(Box::new(schemars::schema::ObjectValidation { object: Some(Box::new(schemars::schema::ObjectValidation {
@ -377,6 +393,7 @@ impl JsonSchema for TypedValue {
Schema::Object(SchemaObject { Schema::Object(SchemaObject {
subschemas: Some(Box::new(schemars::schema::SubschemaValidation { subschemas: Some(Box::new(schemars::schema::SubschemaValidation {
any_of: Some(vec![ any_of: Some(vec![
Schema::Object(pod_id_schema),
Schema::Object(int_schema), Schema::Object(int_schema),
Schema::Object(raw_schema), Schema::Object(raw_schema),
Schema::Object(public_key_schema), Schema::Object(public_key_schema),