use bcx_core::{CapabilityRef, EventId, PolicyEpoch, ValidationError};
use bcx_wire::WireLimits;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum RelationshipKind {
CausedBy,
DelegatedFrom,
RetryOf,
ScheduledBy,
DerivedFrom,
JoinedFrom,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CauseKind {
ExternalRequest,
ExplicitUserAction,
ApplicationAction,
DelegatedServiceCall,
Timer,
QueueMessage,
Retry,
Administrator,
AutonomousAgent,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum OperationAction {
Read,
Create,
Update,
Delete,
Derive,
Execute,
Transfer,
Subscribe,
Publish,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum AdmissionResult {
Allow,
Deny,
Narrow,
RequireApproval,
Quarantine,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum EffectResult {
Completed,
Partial,
Rejected,
Failed,
Cancelled,
TimedOut,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct CauseCapsuleParts<'a> {
pub event_id: EventId,
pub parents: &'a [EventId],
pub relationship: RelationshipKind,
pub cause_kind: CauseKind,
pub action: OperationAction,
pub authority: Option<CapabilityRef>,
pub policy_epoch: Option<PolicyEpoch>,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct CauseCapsule<'a> {
event_id: EventId,
parents: &'a [EventId],
relationship: RelationshipKind,
cause_kind: CauseKind,
action: OperationAction,
authority: Option<CapabilityRef>,
policy_epoch: Option<PolicyEpoch>,
}
impl<'a> CauseCapsule<'a> {
pub fn new(parts: CauseCapsuleParts<'a>, limits: WireLimits) -> Result<Self, ValidationError> {
let capsule = Self {
event_id: parts.event_id,
parents: parts.parents,
relationship: parts.relationship,
cause_kind: parts.cause_kind,
action: parts.action,
authority: parts.authority,
policy_epoch: parts.policy_epoch,
};
match capsule.validate(limits) {
Ok(()) => Ok(capsule),
Err(error) => Err(error),
}
}
pub fn validate(&self, limits: WireLimits) -> Result<(), ValidationError> {
if self.parents.is_empty() {
return Err(ValidationError::Empty);
}
if self.parents.len() > limits.maximum_parent_events() {
return Err(ValidationError::TooLarge);
}
if self.parents.iter().any(|parent| parent == &self.event_id) {
return Err(ValidationError::Malformed);
}
Ok(())
}
#[must_use]
pub const fn event_id(&self) -> EventId {
self.event_id
}
#[must_use]
pub const fn parents(&self) -> &'a [EventId] {
self.parents
}
#[must_use]
pub const fn relationship(&self) -> RelationshipKind {
self.relationship
}
#[must_use]
pub const fn cause_kind(&self) -> CauseKind {
self.cause_kind
}
#[must_use]
pub const fn action(&self) -> OperationAction {
self.action
}
#[must_use]
pub const fn authority(&self) -> Option<CapabilityRef> {
self.authority
}
#[must_use]
pub const fn policy_epoch(&self) -> Option<PolicyEpoch> {
self.policy_epoch
}
}