use crate::actor::ActorRegistration;
use crate::budget::BudgetDimension;
use crate::ids::{ActorId, AttemptId, RunId, TaskId, TenantId};
use crate::platform::{Capability, LedgerEntry, Role, TenantRegistration};
use crate::run::state::RunState;
use crate::run::RunInstance;
use crate::subscription::{EventFilter, SubscriptionId};
use crate::task::task_spec::TaskSpec;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DurabilityPolicy {
Immediate,
Deferred,
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[must_use = "mutation commands should be submitted to a MutationAuthority"]
pub enum MutationCommand {
TaskCreate(TaskCreateCommand),
RunCreate(RunCreateCommand),
RunStateTransition(RunStateTransitionCommand),
AttemptStart(AttemptStartCommand),
AttemptFinish(AttemptFinishCommand),
LeaseAcquire(LeaseAcquireCommand),
LeaseHeartbeat(LeaseHeartbeatCommand),
LeaseExpire(LeaseExpireCommand),
LeaseRelease(LeaseReleaseCommand),
EnginePause(EnginePauseCommand),
EngineResume(EngineResumeCommand),
TaskCancel(TaskCancelCommand),
DependencyDeclare(DependencyDeclareCommand),
RunSuspend(RunSuspendCommand),
RunResume(RunResumeCommand),
BudgetAllocate(BudgetAllocateCommand),
BudgetConsume(BudgetConsumeCommand),
BudgetReplenish(BudgetReplenishCommand),
SubscriptionCreate(SubscriptionCreateCommand),
SubscriptionCancel(SubscriptionCancelCommand),
SubscriptionTrigger(SubscriptionTriggerCommand),
ActorRegister(ActorRegisterCommand),
ActorDeregister(ActorDeregisterCommand),
ActorHeartbeat(ActorHeartbeatCommand),
TenantCreate(TenantCreateCommand),
RoleAssign(RoleAssignCommand),
CapabilityGrant(CapabilityGrantCommand),
CapabilityRevoke(CapabilityRevokeCommand),
LedgerAppend(LedgerAppendCommand),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct EnginePauseCommand {
sequence: u64,
timestamp: u64,
}
impl EnginePauseCommand {
pub fn new(sequence: u64, timestamp: u64) -> Self {
Self { sequence, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct EngineResumeCommand {
sequence: u64,
timestamp: u64,
}
impl EngineResumeCommand {
pub fn new(sequence: u64, timestamp: u64) -> Self {
Self { sequence, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TaskCreateCommand {
sequence: u64,
task_spec: TaskSpec,
timestamp: u64,
}
impl TaskCreateCommand {
pub fn new(sequence: u64, task_spec: TaskSpec, timestamp: u64) -> Self {
Self { sequence, task_spec, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn task_spec(&self) -> &TaskSpec {
&self.task_spec
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RunCreateCommand {
sequence: u64,
run_instance: RunInstance,
}
impl RunCreateCommand {
pub fn new(sequence: u64, run_instance: RunInstance) -> Self {
Self { sequence, run_instance }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn run_instance(&self) -> &RunInstance {
&self.run_instance
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RunStateTransitionCommand {
sequence: u64,
run_id: RunId,
previous_state: RunState,
new_state: RunState,
timestamp: u64,
}
impl RunStateTransitionCommand {
pub fn new(
sequence: u64,
run_id: RunId,
previous_state: RunState,
new_state: RunState,
timestamp: u64,
) -> Self {
Self { sequence, run_id, previous_state, new_state, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn run_id(&self) -> RunId {
self.run_id
}
pub fn previous_state(&self) -> RunState {
self.previous_state
}
pub fn new_state(&self) -> RunState {
self.new_state
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct AttemptStartCommand {
sequence: u64,
run_id: RunId,
attempt_id: AttemptId,
timestamp: u64,
}
impl AttemptStartCommand {
pub fn new(sequence: u64, run_id: RunId, attempt_id: AttemptId, timestamp: u64) -> Self {
Self { sequence, run_id, attempt_id, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn run_id(&self) -> RunId {
self.run_id
}
pub fn attempt_id(&self) -> AttemptId {
self.attempt_id
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum AttemptResultKind {
Success,
Failure,
Timeout,
Suspended,
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[must_use = "attempt outcome should be inspected for state transition decisions"]
pub struct AttemptOutcome {
result: AttemptResultKind,
error: Option<String>,
output: Option<Vec<u8>>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AttemptOutcomeError {
SuccessWithError {
error: String,
},
NonSuccessWithoutError {
result: AttemptResultKind,
},
NonSuccessWithOutput {
result: AttemptResultKind,
},
}
impl std::fmt::Display for AttemptOutcomeError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
AttemptOutcomeError::SuccessWithError { error } => {
write!(f, "Success/Suspended outcome must not have an error detail, got: {error}")
}
AttemptOutcomeError::NonSuccessWithoutError { result } => {
write!(f, "{result:?} outcome must have an error detail")
}
AttemptOutcomeError::NonSuccessWithOutput { result } => {
write!(f, "non-success outcome {result:?} cannot carry output bytes")
}
}
}
}
impl std::error::Error for AttemptOutcomeError {}
impl AttemptOutcome {
pub fn success() -> Self {
Self { result: AttemptResultKind::Success, error: None, output: None }
}
pub fn success_with_output(output: Vec<u8>) -> Self {
let output = if output.is_empty() { None } else { Some(output) };
Self { result: AttemptResultKind::Success, error: None, output }
}
pub fn failure(error: impl Into<String>) -> Self {
Self { result: AttemptResultKind::Failure, error: Some(error.into()), output: None }
}
pub fn timeout(error: impl Into<String>) -> Self {
Self { result: AttemptResultKind::Timeout, error: Some(error.into()), output: None }
}
pub fn suspended() -> Self {
Self { result: AttemptResultKind::Suspended, error: None, output: None }
}
pub fn suspended_with_output(output: Vec<u8>) -> Self {
let output = if output.is_empty() { None } else { Some(output) };
Self { result: AttemptResultKind::Suspended, error: None, output }
}
pub fn from_raw_parts(
result: AttemptResultKind,
error: Option<String>,
output: Option<Vec<u8>>,
) -> Result<Self, AttemptOutcomeError> {
match result {
AttemptResultKind::Success | AttemptResultKind::Suspended => {
if let Some(err) = error {
return Err(AttemptOutcomeError::SuccessWithError { error: err });
}
}
AttemptResultKind::Failure | AttemptResultKind::Timeout => {
if error.is_none() {
return Err(AttemptOutcomeError::NonSuccessWithoutError { result });
}
if output.is_some() {
return Err(AttemptOutcomeError::NonSuccessWithOutput { result });
}
}
}
Ok(Self { result, error, output })
}
pub fn result(&self) -> AttemptResultKind {
self.result
}
pub fn error(&self) -> Option<&str> {
self.error.as_deref()
}
pub fn output(&self) -> Option<&[u8]> {
self.output.as_deref()
}
pub fn into_parts(self) -> (AttemptResultKind, Option<String>, Option<Vec<u8>>) {
(self.result, self.error, self.output)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AttemptFinishCommand {
sequence: u64,
run_id: RunId,
attempt_id: AttemptId,
outcome: AttemptOutcome,
timestamp: u64,
}
impl AttemptFinishCommand {
pub fn new(
sequence: u64,
run_id: RunId,
attempt_id: AttemptId,
outcome: AttemptOutcome,
timestamp: u64,
) -> Self {
Self { sequence, run_id, attempt_id, outcome, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn run_id(&self) -> RunId {
self.run_id
}
pub fn attempt_id(&self) -> AttemptId {
self.attempt_id
}
pub fn outcome(&self) -> &AttemptOutcome {
&self.outcome
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
pub fn result(&self) -> AttemptResultKind {
self.outcome.result
}
pub fn error(&self) -> Option<&str> {
self.outcome.error.as_deref()
}
pub fn output(&self) -> Option<&[u8]> {
self.outcome.output.as_deref()
}
}
macro_rules! lease_command_accessors {
() => {
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn run_id(&self) -> RunId {
self.run_id
}
pub fn owner(&self) -> &str {
&self.owner
}
pub fn expiry(&self) -> u64 {
self.expiry
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
};
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LeaseAcquireCommand {
sequence: u64,
run_id: RunId,
owner: String,
expiry: u64,
timestamp: u64,
}
impl LeaseAcquireCommand {
pub fn new(
sequence: u64,
run_id: RunId,
owner: impl Into<String>,
expiry: u64,
timestamp: u64,
) -> Self {
let owner = owner.into();
debug_assert!(!owner.is_empty(), "lease owner must not be empty");
Self { sequence, run_id, owner, expiry, timestamp }
}
lease_command_accessors!();
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LeaseHeartbeatCommand {
sequence: u64,
run_id: RunId,
owner: String,
expiry: u64,
timestamp: u64,
}
impl LeaseHeartbeatCommand {
pub fn new(
sequence: u64,
run_id: RunId,
owner: impl Into<String>,
expiry: u64,
timestamp: u64,
) -> Self {
let owner = owner.into();
debug_assert!(!owner.is_empty(), "lease owner must not be empty");
Self { sequence, run_id, owner, expiry, timestamp }
}
lease_command_accessors!();
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LeaseExpireCommand {
sequence: u64,
run_id: RunId,
owner: String,
expiry: u64,
timestamp: u64,
}
impl LeaseExpireCommand {
pub fn new(
sequence: u64,
run_id: RunId,
owner: impl Into<String>,
expiry: u64,
timestamp: u64,
) -> Self {
let owner = owner.into();
debug_assert!(!owner.is_empty(), "lease owner must not be empty");
Self { sequence, run_id, owner, expiry, timestamp }
}
lease_command_accessors!();
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LeaseReleaseCommand {
sequence: u64,
run_id: RunId,
owner: String,
expiry: u64,
timestamp: u64,
}
impl LeaseReleaseCommand {
pub fn new(
sequence: u64,
run_id: RunId,
owner: impl Into<String>,
expiry: u64,
timestamp: u64,
) -> Self {
let owner = owner.into();
debug_assert!(!owner.is_empty(), "lease owner must not be empty");
Self { sequence, run_id, owner, expiry, timestamp }
}
lease_command_accessors!();
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct TaskCancelCommand {
sequence: u64,
task_id: TaskId,
timestamp: u64,
}
impl TaskCancelCommand {
pub fn new(sequence: u64, task_id: TaskId, timestamp: u64) -> Self {
Self { sequence, task_id, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn task_id(&self) -> TaskId {
self.task_id
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DependencyDeclareCommand {
sequence: u64,
task_id: TaskId,
depends_on: Vec<TaskId>,
timestamp: u64,
}
impl DependencyDeclareCommand {
pub fn new(sequence: u64, task_id: TaskId, depends_on: Vec<TaskId>, timestamp: u64) -> Self {
debug_assert!(!depends_on.is_empty());
Self { sequence, task_id, depends_on, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn task_id(&self) -> TaskId {
self.task_id
}
pub fn depends_on(&self) -> &[TaskId] {
&self.depends_on
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[must_use]
pub struct MutationOutcome {
sequence: u64,
applied: AppliedMutation,
}
impl MutationOutcome {
pub fn new(sequence: u64, applied: AppliedMutation) -> Self {
Self { sequence, applied }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn applied(&self) -> &AppliedMutation {
&self.applied
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AppliedMutation {
TaskCreate {
task_id: TaskId,
},
RunCreate {
run_id: RunId,
task_id: TaskId,
},
RunStateTransition {
run_id: RunId,
previous_state: RunState,
new_state: RunState,
},
AttemptStart {
run_id: RunId,
attempt_id: AttemptId,
},
AttemptFinish {
run_id: RunId,
attempt_id: AttemptId,
outcome: AttemptOutcome,
},
LeaseAcquire {
run_id: RunId,
owner: String,
expiry: u64,
},
LeaseHeartbeat {
run_id: RunId,
owner: String,
expiry: u64,
},
LeaseExpire {
run_id: RunId,
owner: String,
expiry: u64,
},
LeaseRelease {
run_id: RunId,
owner: String,
expiry: u64,
},
EnginePause,
EngineResume,
TaskCancel {
task_id: TaskId,
},
DependencyDeclare {
task_id: TaskId,
depends_on: Vec<TaskId>,
},
RunSuspend {
run_id: RunId,
},
RunResume {
run_id: RunId,
},
BudgetAllocate {
task_id: TaskId,
dimension: BudgetDimension,
limit: u64,
},
BudgetConsume {
task_id: TaskId,
dimension: BudgetDimension,
amount: u64,
},
BudgetReplenish {
task_id: TaskId,
dimension: BudgetDimension,
new_limit: u64,
},
SubscriptionCreate {
subscription_id: SubscriptionId,
task_id: TaskId,
},
SubscriptionCancel {
subscription_id: SubscriptionId,
},
SubscriptionTrigger {
subscription_id: SubscriptionId,
},
NoOp,
}
pub trait MutationAuthority {
type Error;
fn submit_command(
&mut self,
command: MutationCommand,
durability: DurabilityPolicy,
) -> Result<MutationOutcome, Self::Error>;
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RunSuspendCommand {
sequence: u64,
run_id: RunId,
reason: Option<String>,
timestamp: u64,
}
impl RunSuspendCommand {
pub fn new(sequence: u64, run_id: RunId, reason: Option<String>, timestamp: u64) -> Self {
Self { sequence, run_id, reason, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn run_id(&self) -> RunId {
self.run_id
}
pub fn reason(&self) -> Option<&str> {
self.reason.as_deref()
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RunResumeCommand {
sequence: u64,
run_id: RunId,
timestamp: u64,
}
impl RunResumeCommand {
pub fn new(sequence: u64, run_id: RunId, timestamp: u64) -> Self {
Self { sequence, run_id, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn run_id(&self) -> RunId {
self.run_id
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BudgetAllocateCommand {
sequence: u64,
task_id: TaskId,
dimension: BudgetDimension,
limit: u64,
timestamp: u64,
}
impl BudgetAllocateCommand {
pub fn new(
sequence: u64,
task_id: TaskId,
dimension: BudgetDimension,
limit: u64,
timestamp: u64,
) -> Self {
debug_assert!(limit > 0, "budget limit must be greater than zero");
Self { sequence, task_id, dimension, limit, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn task_id(&self) -> TaskId {
self.task_id
}
pub fn dimension(&self) -> BudgetDimension {
self.dimension
}
pub fn limit(&self) -> u64 {
self.limit
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BudgetConsumeCommand {
sequence: u64,
task_id: TaskId,
dimension: BudgetDimension,
amount: u64,
timestamp: u64,
}
impl BudgetConsumeCommand {
pub fn new(
sequence: u64,
task_id: TaskId,
dimension: BudgetDimension,
amount: u64,
timestamp: u64,
) -> Self {
debug_assert!(amount > 0, "budget consume amount must be greater than zero");
Self { sequence, task_id, dimension, amount, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn task_id(&self) -> TaskId {
self.task_id
}
pub fn dimension(&self) -> BudgetDimension {
self.dimension
}
pub fn amount(&self) -> u64 {
self.amount
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BudgetReplenishCommand {
sequence: u64,
task_id: TaskId,
dimension: BudgetDimension,
new_limit: u64,
timestamp: u64,
}
impl BudgetReplenishCommand {
pub fn new(
sequence: u64,
task_id: TaskId,
dimension: BudgetDimension,
new_limit: u64,
timestamp: u64,
) -> Self {
debug_assert!(new_limit > 0, "budget replenish limit must be greater than zero");
Self { sequence, task_id, dimension, new_limit, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn task_id(&self) -> TaskId {
self.task_id
}
pub fn dimension(&self) -> BudgetDimension {
self.dimension
}
pub fn new_limit(&self) -> u64 {
self.new_limit
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SubscriptionCreateCommand {
sequence: u64,
subscription_id: SubscriptionId,
task_id: TaskId,
filter: EventFilter,
timestamp: u64,
}
impl SubscriptionCreateCommand {
pub fn new(
sequence: u64,
subscription_id: SubscriptionId,
task_id: TaskId,
filter: EventFilter,
timestamp: u64,
) -> Self {
if let EventFilter::BudgetThreshold { threshold_pct, .. } = &filter {
debug_assert!(
*threshold_pct <= 100,
"budget threshold percentage must be 0-100, got {threshold_pct}"
);
}
if let EventFilter::Custom { key } = &filter {
debug_assert!(!key.is_empty(), "custom event key must not be empty");
}
Self { sequence, subscription_id, task_id, filter, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn subscription_id(&self) -> SubscriptionId {
self.subscription_id
}
pub fn task_id(&self) -> TaskId {
self.task_id
}
pub fn filter(&self) -> &EventFilter {
&self.filter
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SubscriptionCancelCommand {
sequence: u64,
subscription_id: SubscriptionId,
timestamp: u64,
}
impl SubscriptionCancelCommand {
pub fn new(sequence: u64, subscription_id: SubscriptionId, timestamp: u64) -> Self {
Self { sequence, subscription_id, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn subscription_id(&self) -> SubscriptionId {
self.subscription_id
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SubscriptionTriggerCommand {
sequence: u64,
subscription_id: SubscriptionId,
timestamp: u64,
}
impl SubscriptionTriggerCommand {
pub fn new(sequence: u64, subscription_id: SubscriptionId, timestamp: u64) -> Self {
Self { sequence, subscription_id, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn subscription_id(&self) -> SubscriptionId {
self.subscription_id
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ActorRegisterCommand {
sequence: u64,
registration: ActorRegistration,
timestamp: u64,
}
impl ActorRegisterCommand {
pub fn new(sequence: u64, registration: ActorRegistration, timestamp: u64) -> Self {
Self { sequence, registration, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn registration(&self) -> &ActorRegistration {
&self.registration
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ActorDeregisterCommand {
sequence: u64,
actor_id: ActorId,
timestamp: u64,
}
impl ActorDeregisterCommand {
pub fn new(sequence: u64, actor_id: ActorId, timestamp: u64) -> Self {
Self { sequence, actor_id, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn actor_id(&self) -> ActorId {
self.actor_id
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ActorHeartbeatCommand {
sequence: u64,
actor_id: ActorId,
timestamp: u64,
}
impl ActorHeartbeatCommand {
pub fn new(sequence: u64, actor_id: ActorId, timestamp: u64) -> Self {
Self { sequence, actor_id, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn actor_id(&self) -> ActorId {
self.actor_id
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TenantCreateCommand {
sequence: u64,
registration: TenantRegistration,
timestamp: u64,
}
impl TenantCreateCommand {
pub fn new(sequence: u64, registration: TenantRegistration, timestamp: u64) -> Self {
Self { sequence, registration, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn registration(&self) -> &TenantRegistration {
&self.registration
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RoleAssignCommand {
sequence: u64,
actor_id: ActorId,
role: Role,
tenant_id: TenantId,
timestamp: u64,
}
impl RoleAssignCommand {
pub fn new(
sequence: u64,
actor_id: ActorId,
role: Role,
tenant_id: TenantId,
timestamp: u64,
) -> Self {
Self { sequence, actor_id, role, tenant_id, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn actor_id(&self) -> ActorId {
self.actor_id
}
pub fn role(&self) -> &Role {
&self.role
}
pub fn tenant_id(&self) -> TenantId {
self.tenant_id
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CapabilityGrantCommand {
sequence: u64,
actor_id: ActorId,
capability: Capability,
tenant_id: TenantId,
timestamp: u64,
}
impl CapabilityGrantCommand {
pub fn new(
sequence: u64,
actor_id: ActorId,
capability: Capability,
tenant_id: TenantId,
timestamp: u64,
) -> Self {
Self { sequence, actor_id, capability, tenant_id, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn actor_id(&self) -> ActorId {
self.actor_id
}
pub fn capability(&self) -> &Capability {
&self.capability
}
pub fn tenant_id(&self) -> TenantId {
self.tenant_id
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CapabilityRevokeCommand {
sequence: u64,
actor_id: ActorId,
capability: Capability,
tenant_id: TenantId,
timestamp: u64,
}
impl CapabilityRevokeCommand {
pub fn new(
sequence: u64,
actor_id: ActorId,
capability: Capability,
tenant_id: TenantId,
timestamp: u64,
) -> Self {
Self { sequence, actor_id, capability, tenant_id, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn actor_id(&self) -> ActorId {
self.actor_id
}
pub fn capability(&self) -> &Capability {
&self.capability
}
pub fn tenant_id(&self) -> TenantId {
self.tenant_id
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LedgerAppendCommand {
sequence: u64,
entry: LedgerEntry,
timestamp: u64,
}
impl LedgerAppendCommand {
pub fn new(sequence: u64, entry: LedgerEntry, timestamp: u64) -> Self {
Self { sequence, entry, timestamp }
}
pub fn sequence(&self) -> u64 {
self.sequence
}
pub fn entry(&self) -> &LedgerEntry {
&self.entry
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
}