1pub use hdk_extensions::hdi;
8pub use hdk_extensions::holo_hash;
9pub use hdk_extensions::hdk;
10pub use hdk_extensions::hdi_extensions;
11pub use hdk_extensions;
12pub use rmpv;
13pub use hc_crud;
14pub use portal_types;
15
16use hdi_extensions::{
17 guest_error,
18};
19use hdk::prelude::*;
20use holo_hash::DnaHash;
21
22
23
24pub type Payload = rmpv::Value;
29
30
31
32pub type RemoteCallInput = RemoteCallDetails<String, String, Payload>;
37
38#[derive(Debug, Deserialize, Serialize, Clone)]
40pub struct CustomRemoteCallInput {
41 pub host: AgentPubKey,
42 pub call: RemoteCallInput,
43}
44
45
46#[derive(Debug, Deserialize, Serialize, Clone)]
48pub struct DnaZomeFunction {
49 pub dna: DnaHash,
50 pub zome: ZomeName,
51 pub function: FunctionName,
52}
53
54
55#[derive(Debug, Serialize, Deserialize, Clone)]
58pub struct RemoteCallDetails<Z,F,I>
59where
60 Z: Into<ZomeName>,
61 F: Into<FunctionName>,
62 I: Serialize + core::fmt::Debug,
63{
64 pub dna: DnaHash,
65 pub zome: Z,
66 pub function: F,
67 pub payload: I,
68}
69
70
71
72pub fn path<T>( base: &str, segments: T ) -> (Path, EntryHash)
77where
78 T: IntoIterator,
79 T::Item: std::fmt::Display,
80{
81 let mut components : Vec<Component> = vec![];
82
83 for seg in base.split(".") {
84 let component = Component::from( format!("{}", seg ).as_bytes().to_vec() );
85 components.push( component );
86 }
87
88 for seg in segments {
89 let component = Component::from( format!("{}", seg ).as_bytes().to_vec() );
90 components.push( component );
91 }
92
93 let path = Path::from( components );
94 let hash = path.path_entry_hash().unwrap();
95
96 ( path, hash )
97}
98
99
100
101pub fn zome_call_response_as_result(response: ZomeCallResponse) -> ExternResult<ExternIO> {
106 Ok( match response {
107 ZomeCallResponse::Ok(bytes)
108 => Ok(bytes),
109 ZomeCallResponse::Unauthorized(zome_call_auth, cell_id, zome, func, agent)
110 => Err(guest_error!(format!("UnauthorizedError( {}, {}, {}, {}, {} )", zome_call_auth, cell_id, zome, func, agent ))),
111 ZomeCallResponse::NetworkError(message)
112 => Err(guest_error!(format!("NetworkError( {} )", message ))),
113 ZomeCallResponse::CountersigningSession(message)
114 => Err(guest_error!(format!("CountersigningSessionError( {} )", message ))),
115 }? )
116}
117
118
119
120#[macro_export]
122macro_rules! call_local_cell {
123 ( $role:literal, $zome:literal, $fn:literal, $($input:tt)+ ) => {
124 {
125 use $crate::hdk::prelude::*;
126 use $crate::hdi_extensions::guest_error;
127
128 call(
129 CallTargetCell::OtherRole( $role.into() ),
130 $zome,
131 $fn.into(),
132 None,
133 $($input)+,
134 ).and_then( |call_response| match call_response {
135 ZomeCallResponse::Ok(extern_io) => Ok(extern_io),
136 ZomeCallResponse::NetworkError(msg) => Err(guest_error!(format!("NetworkError: {}", msg))),
137 ZomeCallResponse::CountersigningSession(msg) => Err(guest_error!(format!("CountersigningSession: {}", msg))),
138 _ => Err(guest_error!(format!("Zome call response: Unauthorized"))),
139 })
140 }
141 };
142}
143
144#[macro_export]
146macro_rules! call_local_cell_decode {
147 ( $role:literal, $zome:literal, $fn:literal, $($input:tt)+ ) => {
148 {
149 use $crate::hdk::prelude::{
150 wasm_error,
151 };
152
153 $crate::call_local_cell!( $role, $zome, $fn, $($input)+ ).and_then(
154 |extern_io| extern_io.decode().map_err(|err| wasm_error!(WasmErrorInner::from(err)) )
155 )
156 }
157 };
158 ( $into_type:ident, $role:literal, $zome:literal, $fn:literal, $($input:tt)+ ) => {
159 {
160 use $crate::hdk::prelude::{
161 wasm_error,
162 };
163
164 $crate::call_local_cell!( $role, $zome, $fn, $($input)+ ).and_then(
165 |extern_io| extern_io.decode::<$into_type>().map_err(|err| wasm_error!(WasmErrorInner::from(err)) )
166 )
167 }
168 };
169}
170
171pub type ZomeFunction<T1,T2> = (T1, T2);
173
174#[derive(Debug, Serialize, Clone)]
176#[allow(non_snake_case)]
177pub struct ListedFunctions {
178 pub Listed: Vec<ZomeFunction<String, String>>,
179}
180
181#[derive(Debug, Serialize)]
183pub struct RegisterHostInput {
184 pub dna: DnaHash,
185 pub granted_functions: ListedFunctions,
186}
187
188#[derive(Debug, Serialize)]
190pub struct RegisterInput<T1,T2>
191where
192 T1: Into<String>,
193 T2: Into<String>,
194{
195 pub dna: DnaHash,
196 pub granted_functions: Vec<ZomeFunction<T1,T2>>,
197}
198
199#[macro_export]
201macro_rules! register {
202 ( $dna:literal, $zome:literal, $fn_name:literal, $($def:tt)* ) => {
203 {
204 use $crate::hdk::prelude::*;
205 use $crate::hc_crud::Entity;
206 use $crate::portal_types::HostEntry;
207
208 let input = $crate::RegisterInput $($def)*;
209 let payload = $crate::RegisterHostInput {
210 dna: input.dna,
211 granted_functions: $crate::ListedFunctions {
212 Listed: input.granted_functions.into_iter()
213 .map( |(zome, func)| (zome.into(), func.into()) )
214 .collect()
215 },
216 };
217
218 type Response = Entity<HostEntry>;
219
220 $crate::call_local_cell_decode!(
221 Response,
222 $dna,
223 $zome,
224 $fn_name,
225 payload
226 )
227 }
228 };
229 ( $dna:literal, $zome:literal, $($def:tt)* ) => {
230 $crate::register!( $dna, $zome, "register_host", $($def)* )
231 };
232 ( $dna:literal, $($def:tt)* ) => {
233 $crate::register!( $dna, "portal_csr", $($def)* )
234 };
235 ( $($def:tt)* ) => {
236 $crate::register!( "portal", $($def)* )
237 };
238}
239
240#[macro_export]
242macro_rules! register_if_exists {
243 ( $($def:tt)* ) => {
244 {
245 use $crate::hdk::prelude::*;
246
247 let result = $crate::register!( $($def)* );
248
249 match result {
250 Err(err) => match err {
251 WasmError {
252 error: WasmErrorInner::Host(ref msg), ..
253 } if msg.contains("Role not found") => Ok(None),
254 err => Err(err),
255 },
256 Ok(value) => Ok(Some(value)),
257 }
258 }
259 };
260}