use std::{collections::HashMap, hash::Hash};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub struct Object {
pub namespace: String,
pub id: String,
}
impl Object {
pub fn new(namespace: impl Into<String>, id: impl Into<String>) -> Self {
Self {
namespace: namespace.into(),
id: id.into(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub struct Relation(pub String);
impl Relation {
pub fn new(name: impl Into<String>) -> Self {
Self(name.into())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum User {
UserId(String),
Userset(Object, Relation),
}
impl User {
pub fn user_id(id: impl Into<String>) -> Self {
Self::UserId(id.into())
}
pub fn userset(object: Object, relation: Relation) -> Self {
Self::Userset(object, relation)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub struct RelationTuple {
pub object: Object,
pub relation: Relation,
pub user: User,
}
impl RelationTuple {
pub fn new(object: Object, relation: Relation, user: User) -> Self {
Self {
object,
relation,
user,
}
}
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct NamespaceConfig {
pub name: String,
pub relations: HashMap<Relation, RelationConfig>,
}
impl NamespaceConfig {
pub fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
relations: HashMap::new(),
}
}
pub fn with_relation(mut self, config: RelationConfig) -> Self {
self.relations.insert(config.name.clone(), config);
self
}
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct RelationConfig {
pub name: Relation,
pub userset_rewrite: Option<UsersetExpression>,
}
impl RelationConfig {
pub fn new(name: Relation) -> Self {
Self {
name,
userset_rewrite: None,
}
}
pub fn with_rewrite(mut self, rewrite: UsersetExpression) -> Self {
self.userset_rewrite = Some(rewrite);
self
}
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum UsersetExpression {
This,
ComputedUserset {
relation: Relation,
},
TupleToUserset {
tupleset_relation: Relation,
computed_userset_relation: Relation,
},
Union(Vec<UsersetExpression>),
Intersection(Vec<UsersetExpression>),
Exclusion {
base: Box<UsersetExpression>,
exclude: Box<UsersetExpression>,
},
}
#[derive(Debug, PartialEq)]
#[non_exhaustive]
pub enum ExpandedUserset {
User(String),
Userset(Object, Relation),
Union(Vec<ExpandedUserset>),
Intersection(Vec<ExpandedUserset>),
Exclusion {
base: Box<ExpandedUserset>,
exclude: Box<ExpandedUserset>,
},
}