use crate::{Caveat, Entity, Relation, RelationshipOperation, Resource, WildCardId};
use super::subject_filter::RelationFilter;
use super::{
ContextualizedCaveat, ObjectReference, Precondition, Relationship, RelationshipFilter,
RelationshipUpdate, SubjectFilter, SubjectReference,
};
pub fn subject_filter<S>(id: Option<S::Id>, relation: Option<S::Relations>) -> SubjectFilter
where
S: Entity,
{
subject_filter_raw(S::object_type(), id, relation.map(|r| r.name()))
}
pub fn subject_filter_raw(
subject_type: impl Into<String>,
id: Option<impl Into<String>>,
relation: Option<impl Into<String>>,
) -> SubjectFilter {
SubjectFilter {
subject_type: subject_type.into(),
optional_subject_id: id.map(Into::into).unwrap_or_default(),
optional_relation: relation.map(|r| RelationFilter { relation: r.into() }),
}
}
pub fn relationship_filter<R>(
resource_id: Option<R::Id>,
resource_id_prefix: Option<String>,
relation: Option<R::Relations>,
subject_filter: Option<SubjectFilter>,
) -> RelationshipFilter
where
R: Resource,
{
relationship_filter_raw(
R::object_type(),
resource_id,
resource_id_prefix,
relation.map(|r| r.name()),
subject_filter,
)
}
pub fn relationship_filter_raw(
resource_type: impl Into<String>,
resource_id: Option<impl Into<String>>,
resource_id_prefix: Option<impl Into<String>>,
relation: Option<impl Into<String>>,
subject_filter: Option<SubjectFilter>,
) -> RelationshipFilter {
RelationshipFilter {
resource_type: resource_type.into(),
optional_resource_id: resource_id.map(Into::into).unwrap_or_default(),
optional_resource_id_prefix: resource_id_prefix.map(Into::into).unwrap_or_default(),
optional_relation: relation.map(Into::into).unwrap_or_default(),
optional_subject_filter: subject_filter,
}
}
pub fn precondition<R>(
operation: super::precondition::Operation,
resource_id: Option<R::Id>,
resource_id_prefix: Option<String>,
relation: Option<R::Relations>,
subject_filter: Option<SubjectFilter>,
) -> Precondition
where
R: Resource,
{
precondition_raw(
operation,
R::object_type(),
resource_id,
resource_id_prefix,
relation.map(|r| r.name()),
subject_filter,
)
}
pub fn precondition_raw(
operation: super::precondition::Operation,
resource_type: impl Into<String>,
resource_id: Option<impl Into<String>>,
resource_id_prefix: Option<impl Into<String>>,
relation: Option<impl Into<String>>,
subject_filter: Option<SubjectFilter>,
) -> Precondition {
Precondition {
operation: operation as i32,
filter: Some(relationship_filter_raw(
resource_type,
resource_id,
resource_id_prefix,
relation,
subject_filter,
)),
}
}
pub fn subject_reference<S>(id: S::Id, relation: Option<S::Relations>) -> SubjectReference
where
S: Entity,
{
subject_reference_raw(id, S::object_type(), relation.map(|r| r.name()))
}
pub fn subject_reference_raw(
id: impl Into<String>,
object_type: impl Into<String>,
relation: Option<impl Into<String>>,
) -> SubjectReference {
SubjectReference {
object: Some(ObjectReference {
object_type: object_type.into(),
object_id: id.into(),
}),
optional_relation: relation.map(Into::into).unwrap_or_default(),
}
}
pub fn object_reference<E>(id: E::Id) -> ObjectReference
where
E: Entity,
{
ObjectReference {
object_type: E::object_type().into(),
object_id: id.into(),
}
}
pub fn wildcard_relationship_update<S, R>(
operation: RelationshipOperation,
resource_id: impl Into<R::Id>,
relation: R::Relations,
) -> RelationshipUpdate
where
S: Entity,
R: Resource,
{
let subject = subject_reference_raw(WildCardId, S::object_type(), None::<String>);
let resource = object_reference::<R>(Into::<R::Id>::into(resource_id));
RelationshipUpdate {
operation: operation as i32,
relationship: Some(Relationship {
resource: Some(resource),
relation: relation.name().to_owned(),
subject: Some(subject),
optional_caveat: None,
}),
}
}
pub fn relationship_update<S, R>(
operation: RelationshipOperation,
subject_id: impl Into<S::Id>,
subject_relation: Option<S::Relations>,
resource_id: impl Into<R::Id>,
relation: R::Relations,
) -> RelationshipUpdate
where
S: Entity,
R: Resource,
{
let subject = subject_reference::<S>(Into::<S::Id>::into(subject_id), subject_relation);
let resource = object_reference::<R>(Into::<R::Id>::into(resource_id));
RelationshipUpdate {
operation: operation as i32,
relationship: Some(Relationship {
resource: Some(resource),
relation: relation.name().to_owned(),
subject: Some(subject),
optional_caveat: None,
}),
}
}
pub fn caveated_relationship_update<S, R, C>(
operation: RelationshipOperation,
subject_id: impl Into<S::Id>,
subject_relation: Option<S::Relations>,
resource_id: impl Into<R::Id>,
relation: R::Relations,
caveat_context: C::ContextStruct,
) -> RelationshipUpdate
where
S: Entity,
R: Resource,
C: Caveat,
{
let subject = subject_reference::<S>(Into::<S::Id>::into(subject_id), subject_relation);
let resource = object_reference::<R>(Into::<R::Id>::into(resource_id));
RelationshipUpdate {
operation: operation as i32,
relationship: Some(Relationship {
resource: Some(resource),
relation: relation.name().to_owned(),
subject: Some(subject),
optional_caveat: Some(ContextualizedCaveat {
caveat_name: C::name().to_owned(),
context: Some(caveat_context.into()),
}),
}),
}
}