Skip to content

Commit

Permalink
feat: add canister query command
Browse files Browse the repository at this point in the history
  • Loading branch information
Hans Larsen committed Sep 20, 2019
1 parent 0be1a56 commit 5893e85
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 1 deletion.
4 changes: 3 additions & 1 deletion dfx/src/commands/canister/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ use clap::{App, ArgMatches, SubCommand};

mod call;
mod install;
mod query;

fn builtins<T>() -> Vec<CliCommand<T>>
where
T: ClientEnv + ProjectConfigEnv,
{
vec![
CliCommand::new(install::construct(), install::exec),
CliCommand::new(call::construct(), call::exec),
CliCommand::new(install::construct(), install::exec),
CliCommand::new(query::construct(), query::exec),
]
}

Expand Down
76 changes: 76 additions & 0 deletions dfx/src/commands/canister/query.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use crate::lib::api_client::{query, Blob, CanisterQueryCall, QueryResponseReply, ReadResponse};
use crate::lib::env::ClientEnv;
use crate::lib::error::{DfxError, DfxResult};
use clap::{App, Arg, ArgMatches, SubCommand};
use tokio::runtime::Runtime;

fn is_number(v: String) -> Result<(), String> {
v.parse::<u64>()
.map_err(|_| String::from("The value must be a number."))
.map(|_| ())
}

pub fn construct() -> App<'static, 'static> {
SubCommand::with_name("query")
.about("Query a canister.")
.arg(
Arg::with_name("canister")
.takes_value(true)
.help("The canister ID (a number) to query.")
.required(true)
.validator(is_number),
)
.arg(
Arg::with_name("method_name")
.help("The query method name file to use.")
.required(true),
)
.arg(
Arg::with_name("arguments")
.help("Arguments to pass to the method.")
.takes_value(true)
.multiple(true),
)
}

pub fn exec<T>(env: &T, args: &ArgMatches<'_>) -> DfxResult
where
T: ClientEnv,
{
// Read the config.
let canister_id = args.value_of("canister").unwrap().parse::<u64>()?;
let method_name = args.value_of("method_name").unwrap();
let arguments: Option<Vec<&str>> = args.values_of("arguments").map(|args| args.collect());

let client = env.get_client();
let install = query(
client,
CanisterQueryCall {
canister_id,
method_name: method_name.to_owned(),
arg: arguments
.map(|args| Blob(Vec::from(args[0])))
.unwrap_or_else(|| Blob(vec![])),
},
);

let mut runtime = Runtime::new().expect("Unable to create a runtime");
match runtime.block_on(install) {
Ok(ReadResponse::Pending) => {
println!("Pending");
Ok(())
}
Ok(ReadResponse::Replied {
reply: QueryResponseReply { arg: Blob(blob) },
}) => {
println!("{}", String::from_utf8_lossy(&blob));
Ok(())
}
Ok(ReadResponse::Rejected {
reject_code,
reject_message,
}) => Err(DfxError::ClientError(reject_code, reject_message)),
Ok(ReadResponse::Unknown) => Err(DfxError::Unknown("Unknown response".to_owned())),
Err(x) => Err(DfxError::from(x)),
}
}

0 comments on commit 5893e85

Please sign in to comment.