use crate::entry_def::EntryVisibility;
use crate::link::LinkTag;
use crate::timestamp::Timestamp;
pub use builder::HeaderBuilder;
pub use builder::HeaderBuilderCommon;
use holo_hash::impl_hashable_content;
use holo_hash::AgentPubKey;
use holo_hash::DnaHash;
use holo_hash::EntryHash;
use holo_hash::HashableContent;
use holo_hash::HeaderHash;
use holo_hash::HoloHashed;
use holochain_serialized_bytes::prelude::*;
pub mod builder;
pub mod conversions;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, SerializedBytes)]
pub struct HeaderHashes(pub Vec<HeaderHash>);
impl From<Vec<HeaderHash>> for HeaderHashes {
fn from(vs: Vec<HeaderHash>) -> Self {
Self(vs)
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, SerializedBytes)]
pub struct HeaderHashedVec(pub Vec<HeaderHashed>);
impl From<Vec<HeaderHashed>> for HeaderHashedVec {
fn from(vs: Vec<HeaderHashed>) -> Self {
Self(vs)
}
}
#[allow(missing_docs)]
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, SerializedBytes)]
#[serde(tag = "type")]
pub enum Header {
Dna(Dna),
AgentValidationPkg(AgentValidationPkg),
InitZomesComplete(InitZomesComplete),
CreateLink(CreateLink),
DeleteLink(DeleteLink),
OpenChain(OpenChain),
CloseChain(CloseChain),
Create(Create),
Update(Update),
Delete(Delete),
}
pub type HeaderHashed = HoloHashed<Header>;
macro_rules! write_into_header {
($($n:ident),*,) => {
$(
impl HeaderInner for $n {
fn into_header(self) -> Header {
Header::$n(self)
}
}
)*
#[derive(serde::Serialize, serde::Deserialize, SerializedBytes, PartialEq, Clone, Debug)]
pub enum HeaderType {
$($n,)*
}
impl From<&Header> for HeaderType {
fn from(header: &Header) -> HeaderType {
match header {
$(
Header::$n(_) => HeaderType::$n,
)*
}
}
}
};
}
pub trait HeaderInner {
fn into_header(self) -> Header;
}
impl<I: HeaderInner> From<I> for Header {
fn from(i: I) -> Self {
i.into_header()
}
}
write_into_header! {
Dna,
AgentValidationPkg,
InitZomesComplete,
CreateLink,
DeleteLink,
OpenChain,
CloseChain,
Create,
Update,
Delete,
}
macro_rules! match_header {
($h:ident => |$i:ident| { $($t:tt)* }) => {
match $h {
Header::Dna($i) => { $($t)* }
Header::AgentValidationPkg($i) => { $($t)* }
Header::InitZomesComplete($i) => { $($t)* }
Header::CreateLink($i) => { $($t)* }
Header::DeleteLink($i) => { $($t)* }
Header::OpenChain($i) => { $($t)* }
Header::CloseChain($i) => { $($t)* }
Header::Create($i) => { $($t)* }
Header::Update($i) => { $($t)* }
Header::Delete($i) => { $($t)* }
}
};
}
impl Header {
pub fn entry_data(&self) -> Option<(&EntryHash, &EntryType)> {
match self {
Self::Create(Create {
entry_hash,
entry_type,
..
}) => Some((entry_hash, entry_type)),
Self::Update(Update {
entry_hash,
entry_type,
..
}) => Some((entry_hash, entry_type)),
_ => None,
}
}
pub fn entry_hash(&self) -> Option<&EntryHash> {
self.entry_data().map(|d| d.0)
}
pub fn entry_type(&self) -> Option<&EntryType> {
self.entry_data().map(|d| d.1)
}
pub fn header_type(&self) -> HeaderType {
self.into()
}
pub fn author(&self) -> &AgentPubKey {
match_header!(self => |i| { &i.author })
}
pub fn timestamp(&self) -> Timestamp {
match_header!(self => |i| { i.timestamp })
}
pub fn header_seq(&self) -> u32 {
match self {
Self::Dna(Dna { .. }) => 0,
Self::AgentValidationPkg(AgentValidationPkg { header_seq, .. })
| Self::InitZomesComplete(InitZomesComplete { header_seq, .. })
| Self::CreateLink(CreateLink { header_seq, .. })
| Self::DeleteLink(DeleteLink { header_seq, .. })
| Self::Delete(Delete { header_seq, .. })
| Self::CloseChain(CloseChain { header_seq, .. })
| Self::OpenChain(OpenChain { header_seq, .. })
| Self::Create(Create { header_seq, .. })
| Self::Update(Update { header_seq, .. }) => *header_seq,
}
}
pub fn prev_header(&self) -> Option<&HeaderHash> {
Some(match self {
Self::Dna(Dna { .. }) => return None,
Self::AgentValidationPkg(AgentValidationPkg { prev_header, .. }) => prev_header,
Self::InitZomesComplete(InitZomesComplete { prev_header, .. }) => prev_header,
Self::CreateLink(CreateLink { prev_header, .. }) => prev_header,
Self::DeleteLink(DeleteLink { prev_header, .. }) => prev_header,
Self::Delete(Delete { prev_header, .. }) => prev_header,
Self::CloseChain(CloseChain { prev_header, .. }) => prev_header,
Self::OpenChain(OpenChain { prev_header, .. }) => prev_header,
Self::Create(Create { prev_header, .. }) => prev_header,
Self::Update(Update { prev_header, .. }) => prev_header,
})
}
}
impl_hashable_content!(Header, Header);
#[derive(
Debug,
Copy,
Clone,
Hash,
PartialEq,
Eq,
PartialOrd,
Ord,
Serialize,
Deserialize,
SerializedBytes,
)]
pub struct ZomeId(u8);
#[derive(
Debug,
Copy,
Clone,
Hash,
PartialEq,
Eq,
PartialOrd,
Ord,
Serialize,
Deserialize,
SerializedBytes,
)]
pub struct EntryDefIndex(pub u8);
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, SerializedBytes)]
pub struct Dna {
pub author: AgentPubKey,
pub timestamp: Timestamp,
pub hash: DnaHash,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, SerializedBytes)]
pub struct AgentValidationPkg {
pub author: AgentPubKey,
pub timestamp: Timestamp,
pub header_seq: u32,
pub prev_header: HeaderHash,
pub membrane_proof: Option<SerializedBytes>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, SerializedBytes)]
pub struct InitZomesComplete {
pub author: AgentPubKey,
pub timestamp: Timestamp,
pub header_seq: u32,
pub prev_header: HeaderHash,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, SerializedBytes)]
pub struct CreateLink {
pub author: AgentPubKey,
pub timestamp: Timestamp,
pub header_seq: u32,
pub prev_header: HeaderHash,
pub base_address: EntryHash,
pub target_address: EntryHash,
pub zome_id: ZomeId,
pub tag: LinkTag,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, SerializedBytes)]
pub struct DeleteLink {
pub author: AgentPubKey,
pub timestamp: Timestamp,
pub header_seq: u32,
pub prev_header: HeaderHash,
pub base_address: EntryHash,
pub link_add_address: HeaderHash,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, SerializedBytes)]
pub struct OpenChain {
pub author: AgentPubKey,
pub timestamp: Timestamp,
pub header_seq: u32,
pub prev_header: HeaderHash,
pub prev_dna_hash: DnaHash,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, SerializedBytes)]
pub struct CloseChain {
pub author: AgentPubKey,
pub timestamp: Timestamp,
pub header_seq: u32,
pub prev_header: HeaderHash,
pub new_dna_hash: DnaHash,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, SerializedBytes, Hash)]
pub struct Create {
pub author: AgentPubKey,
pub timestamp: Timestamp,
pub header_seq: u32,
pub prev_header: HeaderHash,
pub entry_type: EntryType,
pub entry_hash: EntryHash,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, SerializedBytes, Hash)]
pub struct Update {
pub author: AgentPubKey,
pub timestamp: Timestamp,
pub header_seq: u32,
pub prev_header: HeaderHash,
pub original_header_address: HeaderHash,
pub original_entry_address: EntryHash,
pub entry_type: EntryType,
pub entry_hash: EntryHash,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, SerializedBytes)]
pub struct Delete {
pub author: AgentPubKey,
pub timestamp: Timestamp,
pub header_seq: u32,
pub prev_header: HeaderHash,
pub deletes_address: HeaderHash,
pub deletes_entry_address: EntryHash,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, SerializedBytes, Hash)]
pub struct UpdateHeader {
pub author: AgentPubKey,
pub timestamp: Timestamp,
pub header_seq: u32,
pub prev_header: HeaderHash,
pub original_header_address: HeaderHash,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, SerializedBytes, Hash)]
pub struct DeleteHeader {
pub author: AgentPubKey,
pub timestamp: Timestamp,
pub header_seq: u32,
pub prev_header: HeaderHash,
pub deletes_address: HeaderHash,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, SerializedBytes, Hash)]
pub enum EntryType {
AgentPubKey,
App(AppEntryType),
CapClaim,
CapGrant,
}
impl EntryType {
pub fn visibility(&self) -> &EntryVisibility {
match self {
EntryType::AgentPubKey => &EntryVisibility::Public,
EntryType::App(t) => &t.visibility(),
EntryType::CapClaim => &EntryVisibility::Private,
EntryType::CapGrant => &EntryVisibility::Private,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, SerializedBytes, Hash)]
pub struct AppEntryType {
pub(crate) id: EntryDefIndex,
pub(crate) zome_id: ZomeId,
pub(crate) visibility: EntryVisibility,
}
impl AppEntryType {
pub fn new(id: EntryDefIndex, zome_id: ZomeId, visibility: EntryVisibility) -> Self {
Self {
id,
zome_id,
visibility,
}
}
pub fn id(&self) -> EntryDefIndex {
self.id
}
pub fn zome_id(&self) -> ZomeId {
self.zome_id
}
pub fn visibility(&self) -> &EntryVisibility {
&self.visibility
}
}
impl From<EntryDefIndex> for u8 {
fn from(ei: EntryDefIndex) -> Self {
ei.0
}
}
impl EntryDefIndex {
pub fn index(&self) -> usize {
self.0 as usize
}
}
impl ZomeId {
pub fn index(&self) -> usize {
self.0 as usize
}
}