use bincode::{Decode, Encode};
use serde::{Deserialize, Serialize};
use super::{
address::{Address, DimensionVector, RevisionId, SpaceId},
hyperedge::HyperedgeId,
provenance::AuthoringFrameProvenance,
};
#[derive(
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Encode, Decode,
)]
pub struct ArbiterId(pub u64);
pub const RESERVED_ARBITER_ID_THRESHOLD: u64 = 10;
#[derive(
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, Encode, Decode,
)]
pub struct JudgmentId(pub u64);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Encode, Decode)]
pub enum SubjectKind {
Hyperedge,
Node,
Signal,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Encode, Decode)]
pub enum SubjectIdentity {
Hyperedge(HyperedgeId),
Address(Address),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Encode, Decode)]
pub struct SubjectPin {
pub kind: SubjectKind,
pub space: SpaceId,
pub identity: SubjectIdentity,
pub subject_revision: RevisionId,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Encode, Decode)]
pub enum JudgmentVerdict {
Pass,
Fail,
Conflict,
Annotate,
Custom(String),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Encode, Decode)]
pub struct JudgmentRecord {
pub id: JudgmentId,
pub arbiter: ArbiterId,
pub subject: SubjectPin,
pub verdict: JudgmentVerdict,
pub rationale: Option<String>,
pub authoring_frame: Option<AuthoringFrameProvenance>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Encode, Decode)]
pub struct ArbiterStream {
pub id: ArbiterId,
pub assertion_space: SpaceId,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum JudgmentValidationError {
SubjectNotFound { space: SpaceId, revision: RevisionId },
SubjectRevisionMismatch {
expected: RevisionId,
observed: RevisionId,
},
UnknownArbiter(ArbiterId),
InvalidSubjectPin(String),
}
impl std::fmt::Display for JudgmentValidationError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
JudgmentValidationError::SubjectNotFound { space, revision } => {
write!(f, "subject not found in space {space:?} at revision {revision:?}")
}
JudgmentValidationError::SubjectRevisionMismatch { expected, observed } => write!(
f,
"subject revision mismatch: expected {expected:?}, observed {observed:?}"
),
JudgmentValidationError::UnknownArbiter(id) => {
write!(f, "unknown arbiter stream {:?}", id.0)
}
JudgmentValidationError::InvalidSubjectPin(msg) => write!(f, "{msg}"),
}
}
}
pub fn judgment_storage_point(id: JudgmentId) -> DimensionVector {
DimensionVector::new(vec![
(id.0 >> 32) as u32,
(id.0 & 0xFFFF_FFFF) as u32,
])
}
pub fn judgment_id_from_storage_point(point: &DimensionVector) -> Option<JudgmentId> {
if point.coords.len() != 2 {
return None;
}
Some(JudgmentId(
((point.coords[0] as u64) << 32) | (point.coords[1] as u64),
))
}