Skip to content

Commit

Permalink
Add Entity::new_with_tags() and Entity::tag() (#1402)
Browse files Browse the repository at this point in the history
Signed-off-by: Craig Disselkoen <cdiss@amazon.com>
  • Loading branch information
cdisselkoen authored Dec 31, 2024
1 parent d49f766 commit d1f1185
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 14 deletions.
1 change: 1 addition & 0 deletions cedar-policy/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Cedar Language Version: TBD

- Implemented [RFC 48 (schema annotations)](https://github.com/cedar-policy/rfcs/blob/main/text/0048-schema-annotations.md) (#1316)
- New `.isEmpty()` operator on sets (#1358, resolving #1356)
- New `Entity::new_with_tags()` and `Entity::tag()` functions (#1402, resolving #1374)
- Added protobuf schemas and (de)serialization code using on `prost` crate behind the experimental `protobufs` flag.
- Added protobuf and JSON generation code to `cedar-policy-cli`.
- Added a new get helper method to Context that allows easy extraction of generic values from the context by key. This method simplifies the common use case of retrieving values from Context objects.
Expand Down
51 changes: 37 additions & 14 deletions cedar-policy/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,7 @@ impl Entity {
attrs: HashMap<String, RestrictedExpression>,
parents: HashSet<EntityUid>,
) -> Result<Self, EntityAttrEvaluationError> {
// note that we take a "parents" parameter here; we will compute TC when
// the `Entities` object is created
Ok(Self(ast::Entity::new(
uid.into(),
attrs.into_iter().map(|(k, v)| (SmolStr::from(k), v.0)),
parents.into_iter().map(EntityUid::into).collect(),
[],
Extensions::all_available(),
)?))
Self::new_with_tags(uid, attrs, parents, [])
}

/// Create a new `Entity` with no attributes.
Expand All @@ -191,6 +183,27 @@ impl Entity {
))
}

/// Create a new `Entity` with this Uid, attributes, parents, and tags.
///
/// Attribute and tag values are specified here as "restricted expressions".
/// See docs on [`RestrictedExpression`].
pub fn new_with_tags(
uid: EntityUid,
attrs: impl IntoIterator<Item = (String, RestrictedExpression)>,
parents: impl IntoIterator<Item = EntityUid>,
tags: impl IntoIterator<Item = (String, RestrictedExpression)>,
) -> Result<Self, EntityAttrEvaluationError> {
// note that we take a "parents" parameter here, not "ancestors"; we
// will compute TC when the `Entities` object is created
Ok(Self(ast::Entity::new(
uid.into(),
attrs.into_iter().map(|(k, v)| (k.into(), v.0)),
parents.into_iter().map(EntityUid::into).collect(),
tags.into_iter().map(|(k, v)| (k.into(), v.0)),
Extensions::all_available(),
)?))
}

/// Create a new `Entity` with this Uid, no attributes, and no parents.
/// ```
/// # use cedar_policy::{Entity, EntityId, EntityTypeName, EntityUid};
Expand Down Expand Up @@ -240,11 +253,21 @@ impl Entity {
/// assert!(entity.attr("foo").is_none());
/// ```
pub fn attr(&self, attr: &str) -> Option<Result<EvalResult, PartialValueToValueError>> {
let v = match ast::Value::try_from(self.0.get(attr)?.clone()) {
Ok(v) => v,
Err(e) => return Some(Err(e)),
};
Some(Ok(EvalResult::from(v)))
match ast::Value::try_from(self.0.get(attr)?.clone()) {
Ok(v) => Some(Ok(EvalResult::from(v))),
Err(e) => Some(Err(e)),
}
}

/// Get the value for the given tag, or `None` if not present.
///
/// This can also return Some(Err) if the tag is not a value (i.e., is
/// unknown due to partial evaluation).
pub fn tag(&self, tag: &str) -> Option<Result<EvalResult, PartialValueToValueError>> {
match ast::Value::try_from(self.0.get_tag(tag)?.clone()) {
Ok(v) => Some(Ok(EvalResult::from(v))),
Err(e) => Some(Err(e)),
}
}

/// Consume the entity and return the entity's owned Uid, attributes and parents.
Expand Down

0 comments on commit d1f1185

Please sign in to comment.