#[repr(transparent)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Activity(pub String);
impl Activity {
pub fn new(label: impl Into<String>) -> Self {
Self(label.into())
}
#[inline]
pub fn into_inner(self) -> String {
self.0
}
#[inline]
pub fn as_inner(&self) -> &str {
&self.0
}
}
impl From<&str> for Activity {
#[inline]
fn from(s: &str) -> Self {
Activity(s.to_owned())
}
}
impl From<String> for Activity {
#[inline]
fn from(s: String) -> Self {
Activity(s)
}
}
impl AsRef<str> for Activity {
#[inline]
fn as_ref(&self) -> &str {
&self.0
}
}
impl core::fmt::Display for Activity {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(&self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum DeclareTemplate {
Existence,
Absence,
Init,
Existence2,
Existence3,
Absence2,
Absence3,
RespondedExistence,
CoExistence,
Response,
Precedence,
Succession,
AlternateResponse,
AlternatePrecedence,
AlternateSuccession,
ChainResponse,
ChainPrecedence,
ChainSuccession,
NotCoExistence,
NotSuccession,
NotChainSuccession,
ExclusiveChoice,
}
impl DeclareTemplate {
pub fn arity(self) -> usize {
match self {
DeclareTemplate::Existence
| DeclareTemplate::Absence
| DeclareTemplate::Init
| DeclareTemplate::Existence2
| DeclareTemplate::Existence3
| DeclareTemplate::Absence2
| DeclareTemplate::Absence3 => 1,
DeclareTemplate::RespondedExistence
| DeclareTemplate::CoExistence
| DeclareTemplate::Response
| DeclareTemplate::Precedence
| DeclareTemplate::Succession
| DeclareTemplate::AlternateResponse
| DeclareTemplate::AlternatePrecedence
| DeclareTemplate::AlternateSuccession
| DeclareTemplate::ChainResponse
| DeclareTemplate::ChainPrecedence
| DeclareTemplate::ChainSuccession
| DeclareTemplate::NotCoExistence
| DeclareTemplate::NotSuccession
| DeclareTemplate::NotChainSuccession
| DeclareTemplate::ExclusiveChoice => 2,
}
}
pub fn is_negative(self) -> bool {
matches!(
self,
DeclareTemplate::Absence
| DeclareTemplate::Absence2
| DeclareTemplate::Absence3
| DeclareTemplate::NotCoExistence
| DeclareTemplate::NotSuccession
| DeclareTemplate::NotChainSuccession
)
}
pub fn is_chain(self) -> bool {
matches!(
self,
DeclareTemplate::ChainResponse
| DeclareTemplate::ChainPrecedence
| DeclareTemplate::ChainSuccession
| DeclareTemplate::NotChainSuccession
)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum DeclareScope {
SingleObjectScope(String),
MultiObjectScope(Vec<String>),
SynchronizedObjectScope(Vec<String>),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DeclareConstraint {
pub template: DeclareTemplate,
pub activation: Activity,
pub target: Option<Activity>,
pub scope: DeclareScope,
}
impl DeclareConstraint {
pub fn unary(template: DeclareTemplate, activation: Activity, scope: DeclareScope) -> Self {
Self {
template,
activation,
target: None,
scope,
}
}
pub fn binary(
template: DeclareTemplate,
activation: Activity,
target: Activity,
scope: DeclareScope,
) -> Self {
Self {
template,
activation,
target: Some(target),
scope,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OcDeclareConstraint {
pub constraint: DeclareConstraint,
pub object_types: Vec<String>,
pub synchronized: bool,
}
impl OcDeclareConstraint {
pub fn new(constraint: DeclareConstraint, object_types: Vec<String>) -> Self {
Self {
constraint,
object_types,
synchronized: false,
}
}
pub fn synchronized(constraint: DeclareConstraint, object_types: Vec<String>) -> Self {
Self {
constraint,
object_types,
synchronized: true,
}
}
pub fn is_synchronized(&self) -> bool {
self.synchronized
}
#[must_use = "check the shape-check result"]
pub fn validate(&self) -> Result<(), OcDeclareRefusal> {
if self.object_types.is_empty() {
return Err(OcDeclareRefusal::EmptyObjectTypeList);
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum OcDeclareRefusal {
EmptyObjectTypeList,
SynchronizationRequiresMultipleTypes,
ScopeMismatch,
}
impl core::fmt::Display for OcDeclareRefusal {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let law = match self {
OcDeclareRefusal::EmptyObjectTypeList => "EmptyObjectTypeList",
OcDeclareRefusal::SynchronizationRequiresMultipleTypes => {
"SynchronizationRequiresMultipleTypes"
}
OcDeclareRefusal::ScopeMismatch => "ScopeMismatch",
};
write!(f, "OcDeclare refused: {law}")
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum DeclareRefusal {
MissingActivation,
MissingTarget,
InvalidTemplateArity,
EmptyObjectScope,
SynchronizationViolation,
}
impl core::fmt::Display for DeclareRefusal {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let law = match self {
DeclareRefusal::MissingActivation => "MissingActivation",
DeclareRefusal::MissingTarget => "MissingTarget",
DeclareRefusal::InvalidTemplateArity => "InvalidTemplateArity",
DeclareRefusal::EmptyObjectScope => "EmptyObjectScope",
DeclareRefusal::SynchronizationViolation => "SynchronizationViolation",
};
write!(f, "Declare refused: {law}")
}
}
use crate::witness::Join;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum DeclareState {
#[default]
Unknown,
Satisfied,
Violated,
Contradiction,
}
impl Join for DeclareState {
fn join(self, other: Self) -> Self {
match (self, other) {
(DeclareState::Unknown, s) => s,
(s, DeclareState::Unknown) => s,
(DeclareState::Satisfied, DeclareState::Satisfied) => self,
(DeclareState::Violated, DeclareState::Violated) => self,
_ => DeclareState::Contradiction,
}
}
}
impl core::fmt::Display for DeclareState {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let s = match self {
DeclareState::Unknown => "unknown",
DeclareState::Satisfied => "satisfied",
DeclareState::Violated => "violated",
DeclareState::Contradiction => "contradiction",
};
write!(f, "{s}")
}
}