use std::collections::HashMap;
use holochain_zome_types::prelude::*;
use serde::de::DeserializeOwned;
#[derive(Default)]
pub struct InlineZomeSet {
pub integrity_zomes: HashMap<&'static str, InlineIntegrityZome>,
pub integrity_order: Vec<&'static str>,
pub coordinator_zomes: HashMap<&'static str, InlineCoordinatorZome>,
pub dependencies: HashMap<ZomeName, ZomeName>,
}
#[allow(missing_docs)]
pub enum InlineEntryTypes {
A,
B,
C,
}
impl InlineEntryTypes {
pub fn entry_defs() -> Vec<EntryDef> {
vec![Default::default(); 3]
}
}
impl From<InlineEntryTypes> for ZomeEntryTypesKey {
fn from(t: InlineEntryTypes) -> Self {
Self {
zome_index: 0.into(),
type_index: (t as u8).into(),
}
}
}
impl InlineZomeSet {
pub fn new<I, C>(integrity: I, coordinators: C) -> Self
where
I: IntoIterator<Item = (&'static str, String, Vec<EntryDef>, u8)>,
C: IntoIterator<Item = (&'static str, String)>,
{
let integrity_zomes: Vec<_> = integrity
.into_iter()
.map(|(zome_name, uuid, e, links)| {
(zome_name, InlineIntegrityZome::new(uuid, e, links))
})
.collect();
let integrity_order: Vec<_> = integrity_zomes.iter().map(|(n, _)| *n).collect();
assert_eq!(integrity_order.len(), integrity_zomes.len());
Self {
integrity_zomes: integrity_zomes.into_iter().collect(),
integrity_order,
coordinator_zomes: coordinators
.into_iter()
.map(|(zome_name, uuid)| (zome_name, InlineCoordinatorZome::new(uuid)))
.collect(),
..Default::default()
}
}
pub fn new_unique<I, C>(integrity: I, coordinators: C) -> Self
where
I: IntoIterator<Item = (&'static str, Vec<EntryDef>, u8)>,
C: IntoIterator<Item = &'static str>,
{
let integrity_zomes: Vec<_> = integrity
.into_iter()
.map(|(zome_name, e, links)| (zome_name, InlineIntegrityZome::new_unique(e, links)))
.collect();
let integrity_order: Vec<_> = integrity_zomes.iter().map(|(n, _)| *n).collect();
assert_eq!(integrity_order.len(), integrity_zomes.len());
Self {
integrity_zomes: integrity_zomes.into_iter().collect(),
integrity_order,
coordinator_zomes: coordinators
.into_iter()
.map(|zome_name| (zome_name, InlineCoordinatorZome::new_unique()))
.collect(),
..Default::default()
}
}
pub fn new_single(
integrity_zome_name: &'static str,
coordinator_zome_name: &'static str,
integrity_uuid: impl Into<String>,
coordinator_uuid: impl Into<String>,
entry_defs: Vec<EntryDef>,
num_link_types: u8,
) -> Self {
Self::new(
[(
integrity_zome_name,
integrity_uuid.into(),
entry_defs,
num_link_types,
)],
[(coordinator_zome_name, coordinator_uuid.into())],
)
}
pub fn new_unique_single(
integrity_zome_name: &'static str,
coordinator_zome_name: &'static str,
entry_defs: Vec<EntryDef>,
num_link_types: u8,
) -> Self {
Self::new_unique(
[(integrity_zome_name, entry_defs, num_link_types)],
[coordinator_zome_name],
)
}
pub fn function<F, I, O>(self, zome_name: &'static str, name: &str, f: F) -> Self
where
F: Fn(BoxApi, I) -> InlineZomeResult<O> + 'static + Send + Sync,
I: DeserializeOwned + std::fmt::Debug,
O: Serialize + std::fmt::Debug,
{
let Self {
mut integrity_zomes,
mut coordinator_zomes,
dependencies,
integrity_order,
} = self;
match integrity_zomes.remove_entry(zome_name) {
Some((k, v)) => {
integrity_zomes.insert(k, v.function(name, f));
}
None => {
let (k, v) = coordinator_zomes.remove_entry(zome_name).unwrap();
coordinator_zomes.insert(k, v.function(name, f));
}
}
Self {
integrity_zomes,
integrity_order,
coordinator_zomes,
dependencies,
}
}
#[deprecated = "Alias for `function`"]
pub fn callback<F, I, O>(self, zome_name: &'static str, name: &str, f: F) -> Self
where
F: Fn(BoxApi, I) -> InlineZomeResult<O> + 'static + Send + Sync,
I: DeserializeOwned + std::fmt::Debug,
O: Serialize + std::fmt::Debug,
{
self.function(zome_name, name, f)
}
pub fn merge(mut self, other: Self) -> Self {
for (k, v) in other.integrity_zomes {
if self.integrity_zomes.insert(k, v).is_some() {
panic!("InlineZomeSet contains duplicate key {} on merge.", k);
}
}
for (k, v) in other.coordinator_zomes {
if self.coordinator_zomes.insert(k, v).is_some() {
panic!("InlineZomeSet contains duplicate key {} on merge.", k);
}
}
self.integrity_order.extend(other.integrity_order);
self.dependencies.extend(other.dependencies);
self
}
pub fn into_zomes(mut self) -> (Vec<IntegrityZome>, Vec<CoordinatorZome>) {
(
self.integrity_zomes
.into_iter()
.map(|(n, z)| IntegrityZome::new((*n).into(), z.into()))
.collect(),
self.coordinator_zomes
.into_iter()
.map(|(n, z)| {
let mut z = CoordinatorZome::new((*n).into(), z.into());
let dep = self.dependencies.remove(z.zome_name());
if let Some(dep) = dep {
z.set_dependency(dep);
}
z
})
.collect(),
)
}
pub fn with_dependency(mut self, from: &'static str, to: &'static str) -> Self {
assert!(
self.coordinator_zomes.contains_key(from),
"{} -> {}",
to,
from
);
assert!(self.integrity_zomes.contains_key(to), "{} -> {}", to, from);
self.dependencies.insert(from.into(), to.into());
self
}
pub fn get_entry_location(
api: &BoxApi,
index: impl Into<ZomeEntryTypesKey>,
) -> EntryDefLocation {
let scoped_type = api
.zome_info(())
.unwrap()
.zome_types
.entries
.get(index)
.unwrap();
EntryDefLocation::App(AppEntryDefLocation {
zome_index: scoped_type.zome_index,
entry_def_index: scoped_type.zome_type,
})
}
pub fn get_link_filter(api: &BoxApi, index: impl Into<ZomeLinkTypesKey>) -> LinkTypeFilter {
let scoped_type = api
.zome_info(())
.unwrap()
.zome_types
.links
.get(index)
.unwrap();
LinkTypeFilter::single_type(scoped_type.zome_index, scoped_type.zome_type)
}
pub fn dep_link_filter(api: &BoxApi) -> LinkTypeFilter {
let zome_indexes = api
.zome_info(())
.unwrap()
.zome_types
.links
.dependencies()
.collect();
LinkTypeFilter::Dependencies(zome_indexes)
}
}
impl From<(&'static str, InlineIntegrityZome)> for InlineZomeSet {
fn from((z, e): (&'static str, InlineIntegrityZome)) -> Self {
let mut integrity_zomes = HashMap::new();
integrity_zomes.insert(z, e);
let integrity_order = vec![z];
Self {
integrity_zomes,
integrity_order,
..Default::default()
}
}
}