use std::fmt;
use borsh::{BorshDeserialize, BorshSerialize};
use super::actions::EntityMetadata;
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct NodeId(pub String);
impl NodeId {
pub fn new(id: impl Into<String>) -> Self {
Self(id.into())
}
pub fn as_str(&self) -> &str {
&self.0
}
}
impl fmt::Display for NodeId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl From<&str> for NodeId {
fn from(s: &str) -> Self {
Self::new(s)
}
}
impl From<String> for NodeId {
fn from(s: String) -> Self {
Self::new(s)
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, BorshSerialize, BorshDeserialize)]
pub struct MessageId {
pub sender: String,
pub session: u64,
pub seq: u64,
}
impl MessageId {
pub fn new(sender: impl Into<String>, session: u64, seq: u64) -> Self {
Self {
sender: sender.into(),
session,
seq,
}
}
}
impl fmt::Display for MessageId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}:{}:{}", self.sender, self.session, self.seq)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct TimerId(pub u64);
impl TimerId {
pub const fn new(id: u64) -> Self {
Self(id)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum TimerKind {
Sync,
Housekeeping,
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, BorshSerialize, BorshDeserialize)]
pub struct EntityId(pub [u8; 32]);
impl EntityId {
pub const fn from_bytes(bytes: [u8; 32]) -> Self {
Self(bytes)
}
pub fn from_u64(n: u64) -> Self {
let mut bytes = [0u8; 32];
bytes[..8].copy_from_slice(&n.to_le_bytes());
Self(bytes)
}
pub const fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
}
impl fmt::Debug for EntityId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "EntityId({:02x}{:02x}..)", self.0[0], self.0[1])
}
}
impl fmt::Display for EntityId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{:02x}{:02x}..{:02x}{:02x}",
self.0[0], self.0[1], self.0[30], self.0[31]
)
}
}
impl From<[u8; 32]> for EntityId {
fn from(bytes: [u8; 32]) -> Self {
Self(bytes)
}
}
impl From<u64> for EntityId {
fn from(n: u64) -> Self {
Self::from_u64(n)
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, BorshSerialize, BorshDeserialize)]
pub struct DeltaId(pub [u8; 32]);
impl DeltaId {
pub const fn from_bytes(bytes: [u8; 32]) -> Self {
Self(bytes)
}
pub const fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
pub const ZERO: DeltaId = DeltaId([0; 32]);
}
impl fmt::Debug for DeltaId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "DeltaId({:02x}{:02x}..)", self.0[0], self.0[1])
}
}
impl From<[u8; 32]> for DeltaId {
fn from(bytes: [u8; 32]) -> Self {
Self(bytes)
}
}
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct StateDigest(pub [u8; 32]);
impl StateDigest {
pub const fn from_bytes(bytes: [u8; 32]) -> Self {
Self(bytes)
}
pub const fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
pub const ZERO: StateDigest = StateDigest([0; 32]);
}
impl fmt::Debug for StateDigest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "StateDigest({:02x}{:02x}..)", self.0[0], self.0[1])
}
}
impl From<[u8; 32]> for StateDigest {
fn from(bytes: [u8; 32]) -> Self {
Self(bytes)
}
}
#[derive(Clone, Debug)]
pub struct DigestEntity {
pub id: EntityId,
pub data: Vec<u8>,
pub metadata: EntityMetadata,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_node_id() {
let id = NodeId::new("alice");
assert_eq!(id.as_str(), "alice");
assert_eq!(format!("{id}"), "alice");
}
#[test]
fn test_message_id() {
let mid = MessageId::new("alice", 1, 42);
assert_eq!(mid.sender, "alice");
assert_eq!(mid.session, 1);
assert_eq!(mid.seq, 42);
assert_eq!(format!("{mid}"), "alice:1:42");
}
#[test]
fn test_entity_id_from_u64() {
let id = EntityId::from_u64(12345);
let bytes = id.as_bytes();
let n = u64::from_le_bytes(bytes[..8].try_into().unwrap());
assert_eq!(n, 12345);
assert!(bytes[8..].iter().all(|&b| b == 0));
}
#[test]
fn test_entity_id_ordering() {
let id1 = EntityId::from_u64(1);
let id2 = EntityId::from_u64(2);
let id3 = EntityId::from_u64(1);
assert!(id1 < id2);
assert_eq!(id1, id3);
}
}