Trait ic_utils::call::AsyncCall [−][src]
pub trait AsyncCall<Out> where
Out: for<'de> ArgumentDecoder<'de> + Send, { #[must_use] fn call<'async_trait>(
self
) -> Pin<Box<dyn Future<Output = Result<RequestId, AgentError>> + Send + 'async_trait>>
where
Self: 'async_trait; #[must_use] fn call_and_wait<'async_trait, W>(
self,
waiter: W
) -> Pin<Box<dyn Future<Output = Result<Out, AgentError>> + Send + 'async_trait>>
where
W: Waiter,
W: 'async_trait,
Self: 'async_trait; fn and_then<Out2, R, AndThen>(
self,
and_then: AndThen
) -> AndThenAsyncCaller<Out, Out2, Self, R, AndThen>
where
Self: Sized + Send,
Out2: for<'de> ArgumentDecoder<'de> + Send,
R: Future<Output = Result<Out2, AgentError>> + Send,
AndThen: Send + Fn(Out) -> R, { ... } fn map<Out2, Map>(self, map: Map) -> MappedAsyncCaller<Out, Out2, Self, Map>
where
Self: Sized + Send,
Out2: for<'de> ArgumentDecoder<'de> + Send,
Map: Send + Fn(Out) -> Out2, { ... } }
Expand description
A type that implements asynchronous calls (ie. ‘update’ calls). This can call synchronous and return a RequestId, or it can wait for the result by polling the agent, and return a type.
The return type must be a tuple type that represents all the values the return call should be returning.
Required methods
#[must_use]fn call<'async_trait>(
self
) -> Pin<Box<dyn Future<Output = Result<RequestId, AgentError>> + Send + 'async_trait>> where
Self: 'async_trait,
[src]
#[must_use]fn call<'async_trait>(
self
) -> Pin<Box<dyn Future<Output = Result<RequestId, AgentError>> + Send + 'async_trait>> where
Self: 'async_trait,
[src]Execute the call, but returns the RequestId. Waiting on the request Id must be managed by the caller using the Agent directly.
Since the return type is encoded in the trait itself, this can lead to types
that are not compatible to [O] when getting the result from the Request Id.
For example, you might hold a AsyncCallcall()
and poll for
the result, and try to deserialize it as a String. This would be caught by
Rust type system, but in this case it will be checked at runtime (as Request
Id does not have a type associated with it).
#[must_use]fn call_and_wait<'async_trait, W>(
self,
waiter: W
) -> Pin<Box<dyn Future<Output = Result<Out, AgentError>> + Send + 'async_trait>> where
W: Waiter,
W: 'async_trait,
Self: 'async_trait,
[src]
#[must_use]fn call_and_wait<'async_trait, W>(
self,
waiter: W
) -> Pin<Box<dyn Future<Output = Result<Out, AgentError>> + Send + 'async_trait>> where
W: Waiter,
W: 'async_trait,
Self: 'async_trait,
[src]Execute the call, and wait for an answer using a Waiter strategy. The return type is encoded in the trait.
Provided methods
fn and_then<Out2, R, AndThen>(
self,
and_then: AndThen
) -> AndThenAsyncCaller<Out, Out2, Self, R, AndThen> where
Self: Sized + Send,
Out2: for<'de> ArgumentDecoder<'de> + Send,
R: Future<Output = Result<Out2, AgentError>> + Send,
AndThen: Send + Fn(Out) -> R,
[src]
fn and_then<Out2, R, AndThen>(
self,
and_then: AndThen
) -> AndThenAsyncCaller<Out, Out2, Self, R, AndThen> where
Self: Sized + Send,
Out2: for<'de> ArgumentDecoder<'de> + Send,
R: Future<Output = Result<Out2, AgentError>> + Send,
AndThen: Send + Fn(Out) -> R,
[src]Apply a transformation function after the call has been successful. The transformation is applied with the result.
# // This test is ignored because it requires an ic to be running. We run these
# // in the ic-ref workflow.
use ic_agent::{Agent, Principal};
use ic_utils::{Canister, interfaces};
use candid::{Encode, Decode, CandidType};
# let canister_wasm = b"\0asm\x01\0\0\0";
# fn create_identity() -> impl ic_agent::Identity {
# let rng = ring::rand::SystemRandom::new();
# let key_pair = ring::signature::Ed25519KeyPair::generate_pkcs8(&rng)
# .expect("Could not generate a key pair.");
#
# ic_agent::BasicIdentity::from_key_pair(
# ring::signature::Ed25519KeyPair::from_pkcs8(key_pair.as_ref())
# .expect("Could not read the key pair."),
# )
# }
#
# const URL: &'static str = concat!("http://localhost:", env!("IC_REF_PORT"));
#
async fn create_a_canister() -> Result<Principal, Box<dyn std::error::Error>> {
let agent = Agent::builder()
.with_url(URL)
.with_identity(create_identity())
.build()?;
let management_canister = Canister::builder()
.with_agent(&agent)
.with_canister_id("aaaaa-aa")
.with_interface(interfaces::ManagementCanister)
.build()?;
let waiter = garcon::Delay::builder()
.throttle(std::time::Duration::from_millis(500))
.timeout(std::time::Duration::from_secs(60 * 5))
.build();
// Create a canister, then call the management canister to install a base canister
// WASM. This is to show how this API would be used, but is probably not a good
// real use case.
let canister_id = management_canister
.create_canister()
.and_then(|(canister_id,)| async {
management_canister
.install_code(&canister_id, canister_wasm)
.build()
.call_and_wait(waiter)
.await
})
.call_and_wait(waiter.clone())
.await?;
let result = Decode!(response.as_slice(), CreateCanisterResult)?;
let canister_id: Principal = Principal::from_text(&result.canister_id.to_text())?;
Ok(canister_id)
}
# let mut runtime = tokio::runtime::Runtime::new().unwrap();
# runtime.block_on(async {
let canister_id = create_a_canister().await.unwrap();
eprintln!("{}", canister_id);
# });
fn map<Out2, Map>(self, map: Map) -> MappedAsyncCaller<Out, Out2, Self, Map> where
Self: Sized + Send,
Out2: for<'de> ArgumentDecoder<'de> + Send,
Map: Send + Fn(Out) -> Out2,
[src]
Self: Sized + Send,
Out2: for<'de> ArgumentDecoder<'de> + Send,
Map: Send + Fn(Out) -> Out2,
Implementors
impl<'agent, 'canister: 'agent, Out> AsyncCall<Out> for CallForwarder<'agent, 'canister, Out> where
Out: for<'de> ArgumentDecoder<'de> + Send + Sync,
[src]
impl<'agent, 'canister: 'agent, Out> AsyncCall<Out> for CallForwarder<'agent, 'canister, Out> where
Out: for<'de> ArgumentDecoder<'de> + Send + Sync,
[src]fn call<'async_trait>(
self
) -> Pin<Box<dyn Future<Output = Result<RequestId, AgentError>> + Send + 'async_trait>> where
Self: 'async_trait,
[src]
self
) -> Pin<Box<dyn Future<Output = Result<RequestId, AgentError>> + Send + 'async_trait>> where
Self: 'async_trait,
fn call_and_wait<'async_trait, W>(
self,
waiter: W
) -> Pin<Box<dyn Future<Output = Result<Out, AgentError>> + Send + 'async_trait>> where
W: Waiter,
W: 'async_trait,
Self: 'async_trait,
[src]
self,
waiter: W
) -> Pin<Box<dyn Future<Output = Result<Out, AgentError>> + Send + 'async_trait>> where
W: Waiter,
W: 'async_trait,
Self: 'async_trait,
impl<'agent, 'canister: 'agent, T: Sync> AsyncCall<(Principal,)> for CreateCanisterBuilder<'agent, 'canister, T>
[src]
impl<'agent, 'canister: 'agent, T: Sync> AsyncCall<(Principal,)> for CreateCanisterBuilder<'agent, 'canister, T>
[src]fn call<'async_trait>(
self
) -> Pin<Box<dyn Future<Output = Result<RequestId, AgentError>> + Send + 'async_trait>> where
Self: 'async_trait,
[src]
self
) -> Pin<Box<dyn Future<Output = Result<RequestId, AgentError>> + Send + 'async_trait>> where
Self: 'async_trait,
fn call_and_wait<'async_trait, W>(
self,
waiter: W
) -> Pin<Box<dyn Future<Output = Result<(Principal,), AgentError>> + Send + 'async_trait>> where
W: Waiter,
W: 'async_trait,
Self: 'async_trait,
[src]
self,
waiter: W
) -> Pin<Box<dyn Future<Output = Result<(Principal,), AgentError>> + Send + 'async_trait>> where
W: Waiter,
W: 'async_trait,
Self: 'async_trait,
impl<'agent, 'canister: 'agent, T: Sync> AsyncCall<()> for InstallCodeBuilder<'agent, 'canister, T>
[src]
impl<'agent, 'canister: 'agent, T: Sync> AsyncCall<()> for InstallCodeBuilder<'agent, 'canister, T>
[src]fn call<'async_trait>(
self
) -> Pin<Box<dyn Future<Output = Result<RequestId, AgentError>> + Send + 'async_trait>> where
Self: 'async_trait,
[src]
self
) -> Pin<Box<dyn Future<Output = Result<RequestId, AgentError>> + Send + 'async_trait>> where
Self: 'async_trait,
fn call_and_wait<'async_trait, W>(
self,
waiter: W
) -> Pin<Box<dyn Future<Output = Result<(), AgentError>> + Send + 'async_trait>> where
W: Waiter,
W: 'async_trait,
Self: 'async_trait,
[src]
self,
waiter: W
) -> Pin<Box<dyn Future<Output = Result<(), AgentError>> + Send + 'async_trait>> where
W: Waiter,
W: 'async_trait,
Self: 'async_trait,
impl<'agent, 'canister: 'agent, T: Sync> AsyncCall<()> for UpdateCanisterBuilder<'agent, 'canister, T>
[src]
impl<'agent, 'canister: 'agent, T: Sync> AsyncCall<()> for UpdateCanisterBuilder<'agent, 'canister, T>
[src]fn call<'async_trait>(
self
) -> Pin<Box<dyn Future<Output = Result<RequestId, AgentError>> + Send + 'async_trait>> where
Self: 'async_trait,
[src]
self
) -> Pin<Box<dyn Future<Output = Result<RequestId, AgentError>> + Send + 'async_trait>> where
Self: 'async_trait,
fn call_and_wait<'async_trait, W>(
self,
waiter: W
) -> Pin<Box<dyn Future<Output = Result<(), AgentError>> + Send + 'async_trait>> where
W: Waiter,
W: 'async_trait,
Self: 'async_trait,
[src]
self,
waiter: W
) -> Pin<Box<dyn Future<Output = Result<(), AgentError>> + Send + 'async_trait>> where
W: Waiter,
W: 'async_trait,
Self: 'async_trait,
impl<'agent, Out> AsyncCall<Out> for AsyncCaller<'agent, Out> where
Out: for<'de> ArgumentDecoder<'de> + Send,
[src]
impl<'agent, Out> AsyncCall<Out> for AsyncCaller<'agent, Out> where
Out: for<'de> ArgumentDecoder<'de> + Send,
[src]fn call<'async_trait>(
self
) -> Pin<Box<dyn Future<Output = Result<RequestId, AgentError>> + Send + 'async_trait>> where
Self: 'async_trait,
[src]
self
) -> Pin<Box<dyn Future<Output = Result<RequestId, AgentError>> + Send + 'async_trait>> where
Self: 'async_trait,
fn call_and_wait<'async_trait, W>(
self,
waiter: W
) -> Pin<Box<dyn Future<Output = Result<Out, AgentError>> + Send + 'async_trait>> where
W: Waiter,
W: 'async_trait,
Self: 'async_trait,
[src]
self,
waiter: W
) -> Pin<Box<dyn Future<Output = Result<Out, AgentError>> + Send + 'async_trait>> where
W: Waiter,
W: 'async_trait,
Self: 'async_trait,
impl<Out, Out2, Inner, Map> AsyncCall<Out2> for MappedAsyncCaller<Out, Out2, Inner, Map> where
Out: for<'de> ArgumentDecoder<'de> + Send,
Out2: for<'de> ArgumentDecoder<'de> + Send,
Inner: AsyncCall<Out> + Send,
Map: Send + Fn(Out) -> Out2,
[src]
impl<Out, Out2, Inner, Map> AsyncCall<Out2> for MappedAsyncCaller<Out, Out2, Inner, Map> where
Out: for<'de> ArgumentDecoder<'de> + Send,
Out2: for<'de> ArgumentDecoder<'de> + Send,
Inner: AsyncCall<Out> + Send,
Map: Send + Fn(Out) -> Out2,
[src]fn call<'async_trait>(
self
) -> Pin<Box<dyn Future<Output = Result<RequestId, AgentError>> + Send + 'async_trait>> where
Self: 'async_trait,
[src]
self
) -> Pin<Box<dyn Future<Output = Result<RequestId, AgentError>> + Send + 'async_trait>> where
Self: 'async_trait,
fn call_and_wait<'async_trait, W>(
self,
waiter: W
) -> Pin<Box<dyn Future<Output = Result<Out2, AgentError>> + Send + 'async_trait>> where
W: Waiter,
W: 'async_trait,
Self: 'async_trait,
[src]
self,
waiter: W
) -> Pin<Box<dyn Future<Output = Result<Out2, AgentError>> + Send + 'async_trait>> where
W: Waiter,
W: 'async_trait,
Self: 'async_trait,
impl<Out, Out2, Inner, R, AndThen> AsyncCall<Out2> for AndThenAsyncCaller<Out, Out2, Inner, R, AndThen> where
Out: for<'de> ArgumentDecoder<'de> + Send,
Out2: for<'de> ArgumentDecoder<'de> + Send,
Inner: AsyncCall<Out> + Send,
R: Future<Output = Result<Out2, AgentError>> + Send,
AndThen: Send + Fn(Out) -> R,
[src]
impl<Out, Out2, Inner, R, AndThen> AsyncCall<Out2> for AndThenAsyncCaller<Out, Out2, Inner, R, AndThen> where
Out: for<'de> ArgumentDecoder<'de> + Send,
Out2: for<'de> ArgumentDecoder<'de> + Send,
Inner: AsyncCall<Out> + Send,
R: Future<Output = Result<Out2, AgentError>> + Send,
AndThen: Send + Fn(Out) -> R,
[src]fn call<'async_trait>(
self
) -> Pin<Box<dyn Future<Output = Result<RequestId, AgentError>> + Send + 'async_trait>> where
Self: 'async_trait,
[src]
self
) -> Pin<Box<dyn Future<Output = Result<RequestId, AgentError>> + Send + 'async_trait>> where
Self: 'async_trait,
fn call_and_wait<'async_trait, W>(
self,
waiter: W
) -> Pin<Box<dyn Future<Output = Result<Out2, AgentError>> + Send + 'async_trait>> where
W: Waiter,
W: 'async_trait,
Self: 'async_trait,
[src]
self,
waiter: W
) -> Pin<Box<dyn Future<Output = Result<Out2, AgentError>> + Send + 'async_trait>> where
W: Waiter,
W: 'async_trait,
Self: 'async_trait,