spicedb-rust 0.3.4

A client for spicedb
Documentation
use crate::grpc::GrpcResult;
use crate::permission::SpiceDBPermissionClient;
use crate::spicedb::{caveated_relationship_update, wildcard_relationship_update};
use crate::{spicedb, Caveat, Entity, RelationshipOperation, Resource};

use self::spicedb::precondition::Operation;
use self::spicedb::{relationship_update, Precondition};

#[derive(Clone, Debug)]
pub struct WriteRelationshipsRequest {
    client: SpiceDBPermissionClient,
    request: spicedb::WriteRelationshipsRequest,
}

impl WriteRelationshipsRequest {
    pub fn new(client: SpiceDBPermissionClient) -> Self {
        let request = spicedb::WriteRelationshipsRequest {
            updates: vec![],
            optional_preconditions: vec![],
        };
        WriteRelationshipsRequest { client, request }
    }

    pub fn add_precondition_raw(&mut self, precondition: Precondition) -> &mut Self {
        self.request.optional_preconditions.push(precondition);
        self
    }

    pub fn add_relationship_raw(&mut self, relationship: spicedb::RelationshipUpdate) -> &mut Self {
        self.request.updates.push(relationship);
        self
    }

    pub fn add_precondition<R>(
        &mut self,
        operation: Operation,
        resource_id: Option<R::Id>,
        resource_id_prefix: Option<String>,
        relation: Option<R::Relations>,
        subject_filter: Option<spicedb::SubjectFilter>,
    ) -> &mut Self
    where
        R: Resource,
    {
        let precondition = spicedb::precondition::<R>(
            operation,
            resource_id,
            resource_id_prefix,
            relation,
            subject_filter,
        );
        self.request.optional_preconditions.push(precondition);
        self
    }

    pub fn add_wildcard_relationship<S, R>(
        &mut self,
        operation: RelationshipOperation,
        resource_id: impl Into<R::Id>,
        relation: R::Relations,
    ) -> &mut Self
    where
        S: Entity,
        R: Resource,
    {
        self.request
            .updates
            .push(wildcard_relationship_update::<S, R>(
                operation,
                resource_id,
                relation,
            ));
        self
    }

    pub fn add_relationship<S, R>(
        &mut self,
        operation: RelationshipOperation,
        subject_id: impl Into<S::Id>,
        subject_relation: Option<S::Relations>,
        resource_id: impl Into<R::Id>,
        relation: R::Relations,
    ) -> &mut Self
    where
        S: Entity,
        R: Resource,
    {
        self.request.updates.push(relationship_update::<S, R>(
            operation,
            subject_id,
            subject_relation,
            resource_id,
            relation,
        ));
        self
    }

    pub fn add_caveated_relationship<S, R, C>(
        &mut self,
        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,
    ) -> &mut Self
    where
        S: Entity,
        R: Resource,
        C: Caveat,
    {
        self.request
            .updates
            .push(caveated_relationship_update::<S, R, C>(
                operation,
                subject_id,
                subject_relation,
                resource_id,
                relation,
                caveat_context,
            ));
        self
    }

    pub async fn send(mut self) -> GrpcResult<spicedb::ZedToken> {
        let resp = self
            .client
            .write_relationships(self.request)
            .await?
            .into_inner();
        resp.written_at
            .ok_or_else(|| tonic::Status::internal("Invalid ZedToken"))
    }
}