use std::fmt;
use frame_core::component::ComponentId;
use haematite::{BranchKind, Hash};
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct EntityId([u8; 32]);
impl EntityId {
#[must_use]
pub fn of(bytes: &[u8]) -> Self {
Self(Hash::of(bytes).into_bytes())
}
#[must_use]
pub const fn from_bytes(bytes: [u8; 32]) -> Self {
Self(bytes)
}
#[must_use]
pub const fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
}
impl fmt::Display for EntityId {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
for byte in self.0 {
write!(formatter, "{byte:02x}")?;
}
Ok(())
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct CrossComponentRef {
pub target: ComponentId,
pub entity: EntityId,
}
impl CrossComponentRef {
#[must_use]
pub const fn new(target: ComponentId, entity: EntityId) -> Self {
Self { target, entity }
}
#[must_use]
pub fn to_bytes(self) -> [u8; crate::codec::CROSS_COMPONENT_REF_WIDTH] {
crate::codec::encode_cross_component_ref(self)
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self, crate::StateError> {
crate::codec::decode_cross_component_ref(bytes)
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum ReferenceTargetState {
NeverInstalled,
Installing,
Archiving {
generation: u64,
},
Archived {
generation: u64,
},
}
impl fmt::Display for ReferenceTargetState {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NeverInstalled => formatter.write_str("never installed"),
Self::Installing => formatter.write_str("installing"),
Self::Archiving { generation } => {
write!(formatter, "archiving generation {generation}")
}
Self::Archived { generation } => write!(formatter, "archived generation {generation}"),
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum MergePolicy {
Lww,
VectorClock,
Custom(String),
}
impl fmt::Display for MergePolicy {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Lww => formatter.write_str("lww"),
Self::VectorClock => formatter.write_str("vector-clock"),
Self::Custom(name) => write!(formatter, "custom:{name}"),
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ComponentSchema {
pub merge_policy: MergePolicy,
}
impl ComponentSchema {
#[must_use]
pub const fn lww() -> Self {
Self {
merge_policy: MergePolicy::Lww,
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct AbandonedWork {
pub branch: String,
pub kind: BranchKind,
pub last_root: Hash,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Archive {
pub generation: u64,
pub snapshot_name: String,
pub root: Hash,
pub abandoned_work: Vec<AbandonedWork>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct MergeRecord {
pub sequence: u64,
pub policy: MergePolicy,
pub source_branch: String,
pub destination_branch: String,
pub source_root: Hash,
pub destination_root_before: Hash,
pub merged_content_root: Hash,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ReconcileAction {
InstallBranchCreated {
component: ComponentId,
},
OrphanedByCrash {
component: ComponentId,
generation: u64,
},
ArchiveFinalized {
component: ComponentId,
generation: u64,
},
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct ReconcileReport {
pub healthy_active: usize,
pub actions: Vec<ReconcileAction>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) enum MetaState {
Installing,
Active,
Archiving {
generation: u64,
abandoned_work: Vec<AbandonedWork>,
},
Archived {
generation: u64,
abandoned_work: Vec<AbandonedWork>,
},
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) struct MetaRecord {
pub(crate) component: ComponentId,
pub(crate) incarnation: u64,
pub(crate) schema: ComponentSchema,
pub(crate) state: MetaState,
}