spicedb-rust 0.3.4

A client for spicedb
Documentation
use crate::grpc::GrpcResult;
use crate::permission::SpiceDBPermissionClient;
use crate::spicedb::wrappers::Consistency;
use crate::{spicedb, Actor, Permission, Resource};

#[derive(Debug)]
pub struct CheckPermissionRequest<R> {
    client: SpiceDBPermissionClient,
    request: spicedb::CheckPermissionRequest,
    _phantom: std::marker::PhantomData<R>,
}

impl<R> CheckPermissionRequest<R>
where
    R: Resource,
{
    pub fn new(client: SpiceDBPermissionClient) -> Self {
        let request = spicedb::CheckPermissionRequest {
            ..Default::default()
        };
        CheckPermissionRequest {
            client,
            request,
            _phantom: std::marker::PhantomData,
        }
    }

    pub fn permission(&mut self, permission: R::Permissions) -> &mut Self {
        permission.name().clone_into(&mut self.request.permission);
        self
    }

    pub fn enable_tracing(&mut self) -> &mut Self {
        self.request.with_tracing = true;
        self
    }

    pub fn context(&mut self, context: impl Into<prost_types::Struct>) -> &mut Self {
        self.request.context = Some(context.into());
        self
    }

    pub fn subject(&mut self, subject: spicedb::SubjectReference) -> &mut Self {
        self.request.subject = Some(subject);
        self
    }

    pub fn actor(&mut self, actor: &impl Actor) -> &mut Self {
        self.subject(actor.to_subject())
    }

    pub fn resource(&mut self, resource: spicedb::ObjectReference) -> &mut Self {
        self.request.resource = Some(resource);
        self
    }

    pub fn consistency(&mut self, consistency: Consistency) -> &mut Self {
        self.request.consistency = Some(consistency.into());
        self
    }

    pub async fn send(mut self) -> GrpcResult<spicedb::CheckPermissionResponse> {
        if self.request.resource.is_none() {
            return Err(tonic::Status::invalid_argument("resource is required"));
        }
        if self.request.permission.is_empty() {
            return Err(tonic::Status::invalid_argument("permission is required"));
        }
        if self.request.subject.is_none() {
            return Err(tonic::Status::invalid_argument("subject is required"));
        }
        let resp = self
            .client
            .check_permission(self.request)
            .await?
            .into_inner();
        Ok(resp)
    }
}