@@ -440,11 +440,13 @@ pub(crate) enum AttributeAccess {
440
440
}
441
441
442
442
impl AttributeAccess {
443
+ /// Construct an `AttributeAccess` access from a `GetAttr` expression `expr.attr`.
443
444
pub ( crate ) fn from_expr (
444
445
req_env : & RequestEnv ,
445
446
mut expr : & Expr < Option < Type > > ,
447
+ attr : SmolStr ,
446
448
) -> AttributeAccess {
447
- let mut attrs: Vec < SmolStr > = Vec :: new ( ) ;
449
+ let mut attrs: Vec < SmolStr > = vec ! [ attr ] ;
448
450
loop {
449
451
if let Some ( Type :: EntityOrRecord ( EntityRecordKind :: Entity ( lub) ) ) = expr. data ( ) {
450
452
return AttributeAccess :: EntityLUB ( lub. clone ( ) , attrs) ;
@@ -525,7 +527,7 @@ impl Display for AttributeAccess {
525
527
// optional attribute without a guard, then the help message is also printed.
526
528
#[ cfg( test) ]
527
529
mod test_attr_access {
528
- use cedar_policy_core:: ast:: { EntityType , EntityUID , Expr , ExprBuilder , Var } ;
530
+ use cedar_policy_core:: ast:: { EntityType , EntityUID , Expr , ExprBuilder , ExprKind , Var } ;
529
531
530
532
use crate :: {
531
533
types:: { OpenTag , RequestEnv , Type } ,
@@ -548,7 +550,11 @@ mod test_attr_access {
548
550
resource_slot : None ,
549
551
} ;
550
552
551
- let access = AttributeAccess :: from_expr ( & env, attr_access) ;
553
+ let ExprKind :: GetAttr { expr, attr } = attr_access. expr_kind ( ) else {
554
+ panic ! ( "Can only test `AttributeAccess::from_expr` for `GetAttr` expressions" ) ;
555
+ } ;
556
+
557
+ let access = AttributeAccess :: from_expr ( & env, expr, attr. clone ( ) ) ;
552
558
assert_eq ! (
553
559
access. to_string( ) . as_str( ) ,
554
560
msg. as_ref( ) ,
@@ -603,6 +609,21 @@ mod test_attr_access {
603
609
) ;
604
610
}
605
611
612
+ #[ test]
613
+ fn entity_type_attr_access ( ) {
614
+ let e = ExprBuilder :: with_data ( Some ( Type :: named_entity_reference_from_str ( "Thing" ) ) )
615
+ . get_attr (
616
+ ExprBuilder :: with_data ( Some ( Type :: named_entity_reference_from_str ( "User" ) ) )
617
+ . var ( Var :: Principal ) ,
618
+ "thing" . into ( ) ,
619
+ ) ;
620
+ assert_message_and_help ( & e, "`thing` for entity type User" , "e has thing" ) ;
621
+ let e = ExprBuilder :: new ( ) . get_attr ( e, "bar" . into ( ) ) ;
622
+ assert_message_and_help ( & e, "`bar` for entity type Thing" , "e has bar" ) ;
623
+ let e = ExprBuilder :: new ( ) . get_attr ( e, "baz" . into ( ) ) ;
624
+ assert_message_and_help ( & e, "`bar.baz` for entity type Thing" , "e.bar has baz" ) ;
625
+ }
626
+
606
627
#[ test]
607
628
fn other_access ( ) {
608
629
let e = ExprBuilder :: new ( ) . get_attr (
0 commit comments