pub use hdk_extensions::hdi;
pub use hdk_extensions::holo_hash;
pub use hdk_extensions::hdk;
pub use hdk_extensions::hdi_extensions;
pub use hdk_extensions;
pub use rmpv;
pub use hc_crud;
pub use portal_types;
use hdi_extensions::{
guest_error,
};
use hdk::prelude::*;
use hdk::hash_path::path::{ Component };
use holo_hash::DnaHash;
pub type Payload = rmpv::Value;
pub type RemoteCallInput = RemoteCallDetails<String, String, Payload>;
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct CustomRemoteCallInput {
pub host: AgentPubKey,
pub call: RemoteCallInput,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct DnaZomeFunction {
pub dna: DnaHash,
pub zome: ZomeName,
pub function: FunctionName,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct RemoteCallDetails<Z,F,I>
where
Z: Into<ZomeName>,
F: Into<FunctionName>,
I: Serialize + core::fmt::Debug,
{
pub dna: DnaHash,
pub zome: Z,
pub function: F,
pub payload: I,
}
pub fn path<T>( base: &str, segments: T ) -> (Path, EntryHash)
where
T: IntoIterator,
T::Item: std::fmt::Display,
{
let mut components : Vec<Component> = vec![];
for seg in base.split(".") {
let component = Component::from( format!("{}", seg ).as_bytes().to_vec() );
components.push( component );
}
for seg in segments {
let component = Component::from( format!("{}", seg ).as_bytes().to_vec() );
components.push( component );
}
let path = Path::from( components );
let hash = path.path_entry_hash().unwrap();
( path, hash )
}
pub fn zome_call_response_as_result(response: ZomeCallResponse) -> ExternResult<ExternIO> {
Ok( match response {
ZomeCallResponse::Ok(bytes)
=> Ok(bytes),
ZomeCallResponse::Unauthorized(zome_call_auth, cell_id, zome, func, agent)
=> Err(guest_error!(format!("UnauthorizedError( {}, {}, {}, {}, {} )", zome_call_auth, cell_id, zome, func, agent ))),
ZomeCallResponse::NetworkError(message)
=> Err(guest_error!(format!("NetworkError( {} )", message ))),
ZomeCallResponse::CountersigningSession(message)
=> Err(guest_error!(format!("CountersigningSessionError( {} )", message ))),
}? )
}
#[macro_export]
macro_rules! call_local_cell {
( $role:literal, $zome:literal, $fn:literal, $($input:tt)+ ) => {
{
use $crate::hdk::prelude::*;
use $crate::hdi_extensions::guest_error;
call(
CallTargetCell::OtherRole( $role.into() ),
$zome,
$fn.into(),
None,
$($input)+,
).and_then( |call_response| match call_response {
ZomeCallResponse::Ok(extern_io) => Ok(extern_io),
ZomeCallResponse::NetworkError(msg) => Err(guest_error!(format!("NetworkError: {}", msg))),
ZomeCallResponse::CountersigningSession(msg) => Err(guest_error!(format!("CountersigningSession: {}", msg))),
_ => Err(guest_error!(format!("Zome call response: Unauthorized"))),
})
}
};
}
#[macro_export]
macro_rules! call_local_cell_decode {
( $role:literal, $zome:literal, $fn:literal, $($input:tt)+ ) => {
{
use $crate::hdk::prelude::{
wasm_error,
};
$crate::call_local_cell!( $role, $zome, $fn, $($input)+ ).and_then(
|extern_io| extern_io.decode().map_err(|err| wasm_error!(WasmErrorInner::from(err)) )
)
}
};
( $into_type:ident, $role:literal, $zome:literal, $fn:literal, $($input:tt)+ ) => {
{
use $crate::hdk::prelude::{
wasm_error,
};
$crate::call_local_cell!( $role, $zome, $fn, $($input)+ ).and_then(
|extern_io| extern_io.decode::<$into_type>().map_err(|err| wasm_error!(WasmErrorInner::from(err)) )
)
}
};
}
pub type ZomeFunction<T1,T2> = (T1, T2);
#[derive(Debug, Serialize, Clone)]
#[allow(non_snake_case)]
pub struct ListedFunctions {
pub Listed: Vec<ZomeFunction<String, String>>,
}
#[derive(Debug, Serialize)]
pub struct RegisterHostInput {
pub dna: DnaHash,
pub granted_functions: ListedFunctions,
}
#[derive(Debug, Serialize)]
pub struct RegisterInput<T1,T2>
where
T1: Into<String>,
T2: Into<String>,
{
pub dna: DnaHash,
pub granted_functions: Vec<ZomeFunction<T1,T2>>,
}
#[macro_export]
macro_rules! register {
( $dna:literal, $zome:literal, $fn_name:literal, $($def:tt)* ) => {
{
use $crate::hdk::prelude::*;
use $crate::hc_crud::Entity;
use $crate::portal_types::HostEntry;
let input = $crate::RegisterInput $($def)*;
let payload = $crate::RegisterHostInput {
dna: input.dna,
granted_functions: $crate::ListedFunctions {
Listed: input.granted_functions.into_iter()
.map( |(zome, func)| (zome.into(), func.into()) )
.collect()
},
};
type Response = Entity<HostEntry>;
$crate::call_local_cell_decode!(
Response,
$dna,
$zome,
$fn_name,
payload
)
}
};
( $dna:literal, $zome:literal, $($def:tt)* ) => {
$crate::register!( $dna, $zome, "register_host", $($def)* )
};
( $dna:literal, $($def:tt)* ) => {
$crate::register!( $dna, "portal_csr", $($def)* )
};
( $($def:tt)* ) => {
$crate::register!( "portal", $($def)* )
};
}
#[macro_export]
macro_rules! register_if_exists {
( $($def:tt)* ) => {
{
use $crate::hdk::prelude::*;
let result = $crate::register!( $($def)* );
match result {
Err(err) => match err {
WasmError {
error: WasmErrorInner::Host(ref msg), ..
} if msg.contains("Role not found") => Ok(None),
err => Err(err),
},
Ok(value) => Ok(Some(value)),
}
}
};
}