diff --git a/ic-utils/src/canister.rs b/ic-utils/src/canister.rs index c4c04ad7..2e0748d1 100644 --- a/ic-utils/src/canister.rs +++ b/ic-utils/src/canister.rs @@ -1,5 +1,6 @@ use crate::call::{AsyncCaller, SyncCaller}; use candid::de::ArgumentDecoder; +use candid::parser::value::IDLValue; use candid::ser::IDLBuilder; use candid::CandidType; use ic_agent::{Agent, AgentError}; @@ -192,6 +193,25 @@ impl Argument { } } + /// Add an IDLValue Argument. If the current value of Argument is Raw, will set the + /// result to an error. If the current value is an error, will do nothing. + pub fn push_value_arg(&mut self, arg: IDLValue) { + match self.0 { + Ok(ArgumentType::Idl(ref mut idl_builder)) => { + let result = idl_builder.value_arg(&arg); + if let Err(e) = result { + self.0 = Err(AgentError::CandidError(Box::new(e))) + } + } + Ok(ArgumentType::Raw(_)) => { + self.0 = Err(AgentError::MessageError( + "Cannot overwrite a Raw Argument with a non-raw argument.".to_owned(), + )) + } + _ => {} + } + } + /// Set the argument as raw, replacing any value that was there before. If the /// current argument was an error, does nothing. pub fn set_raw_arg(&mut self, arg: Vec) { @@ -258,6 +278,17 @@ impl<'agent, 'canister: 'agent, Interface> SyncCallBuilder<'agent, 'canister, In self } + /// Add an argument to the candid argument list. This requires Candid arguments, if + /// there is a raw argument set (using [with_arg_raw]), this will fail. + /// TODO: make this method unnecessary https://github.com/dfinity/agent-rs/issues/132 + pub fn with_value_arg( + mut self, + arg: IDLValue, + ) -> SyncCallBuilder<'agent, 'canister, Interface> { + self.arg.push_value_arg(arg); + self + } + /// Replace the argument with raw argument bytes. This will overwrite the current /// argument set, so calling this method twice will discard the first argument. pub fn with_arg_raw(mut self, arg: Vec) -> SyncCallBuilder<'agent, 'canister, Interface> { diff --git a/ic-utils/src/interfaces/http_request.rs b/ic-utils/src/interfaces/http_request.rs index d603d865..e171b6e6 100644 --- a/ic-utils/src/interfaces/http_request.rs +++ b/ic-utils/src/interfaces/http_request.rs @@ -1,6 +1,7 @@ use crate::call::SyncCall; use crate::canister::CanisterBuilder; use crate::Canister; +use candid::parser::value::IDLValue; use candid::{CandidType, Deserialize}; use ic_agent::export::Principal; use ic_agent::Agent; @@ -9,7 +10,7 @@ use std::fmt::Debug; #[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq)] pub struct HttpRequestCanister; -#[derive(CandidType, Deserialize)] +#[derive(CandidType, Clone, Deserialize)] pub struct HeaderField(pub String, pub String); #[derive(CandidType, Deserialize)] @@ -27,6 +28,14 @@ pub struct HttpResponse { pub headers: Vec, #[serde(with = "serde_bytes")] pub body: Vec, + pub next_token: Option, +} + +#[derive(CandidType, Deserialize)] +pub struct NextHttpResponse { + #[serde(with = "serde_bytes")] + pub body: Vec, + pub next_token: Option, } impl HttpRequestCanister { @@ -67,4 +76,13 @@ impl<'agent> Canister<'agent, HttpRequestCanister> { }) .build() } + + pub fn http_request_next<'canister: 'agent>( + &'canister self, + token: IDLValue, + ) -> impl 'agent + SyncCall<(NextHttpResponse,)> { + self.query_("http_request_next") + .with_value_arg(token) + .build() + } }