scuffle_cedar_policy/
entity.rs

1use std::collections::BTreeMap;
2
3use crate::{CedarChild, CedarEntity, CedarId, EntityTypeName, EntityUid};
4
5#[derive(serde_derive::Serialize)]
6struct StaticEntityUid {
7    #[serde(rename = "type")]
8    ty: EntityTypeName,
9    id: smol_str::SmolStr,
10}
11
12/// A cedar entity
13#[derive(serde_derive::Serialize, bon::Builder)]
14#[builder(start_fn(
15    name = builder_internal,
16    vis = "",
17))]
18pub struct Entity<E>
19where
20    E: CedarEntity,
21{
22    #[builder(start_fn)]
23    uid: StaticEntityUid,
24
25    #[builder(start_fn)]
26    attrs: E::Attrs,
27
28    #[builder(field)]
29    parents: Vec<StaticEntityUid>,
30    #[builder(field)]
31    #[serde(skip_serializing_if = "BTreeMap::is_empty")]
32    tags: BTreeMap<smol_str::SmolStr, E::TagType>,
33}
34
35impl<E: CedarEntity, S: entity_builder::IsComplete> From<EntityBuilder<E, S>> for Entity<E> {
36    fn from(value: EntityBuilder<E, S>) -> Self {
37        value.build()
38    }
39}
40
41impl<E: CedarEntity> Entity<E> {
42    /// Create a builder for an entity by providing the entity id as well as the attrs for the entity.
43    pub fn builder(id: E::Id, attrs: E::Attrs) -> EntityBuilder<E> {
44        Self::builder_internal(
45            StaticEntityUid {
46                ty: E::TYPE_NAME,
47                id: id.into_smol_string(),
48            },
49            attrs,
50        )
51    }
52}
53
54impl<E: CedarEntity, S: entity_builder::State> EntityBuilder<E, S> {
55    /// Add a parent to this entity by providing its EntityId
56    pub fn parent<P>(mut self, id: impl Into<P::Id>) -> Self
57    where
58        E: CedarChild<P>,
59        P: CedarEntity,
60    {
61        self.parents.push(StaticEntityUid {
62            ty: P::TYPE_NAME,
63            id: id.into().into_smol_string(),
64        });
65        self
66    }
67
68    /// Add a tag to this entity by providing a key and the tag itself.
69    pub fn tag(mut self, key: impl Into<smol_str::SmolStr>, value: impl Into<E::TagType>) -> Self {
70        self.tags.insert(key.into(), value.into());
71        self
72    }
73}
74
75impl<E: CedarEntity> Entity<E> {
76    /// Get the [EntityUid] that represents this entity.
77    pub fn entity_uid(&self) -> EntityUid<E> {
78        EntityUid::new_from_str(self.uid.id.clone())
79    }
80}