@@ -3,9 +3,7 @@ use super::helper::{did_to_canister_info, MyHelper};
33use super :: token:: { ParserError , Tokenizer } ;
44use super :: value:: Value ;
55use anyhow:: { anyhow, Context } ;
6- use candid:: {
7- parser:: configs:: Configs , parser:: value:: IDLValue , types:: Function , IDLArgs , Principal , TypeEnv ,
8- } ;
6+ use candid:: { parser:: configs:: Configs , parser:: value:: IDLValue , Principal , TypeEnv } ;
97use ic_agent:: Agent ;
108use pretty_assertions:: { assert_eq, assert_ne} ;
119use std:: path:: { Path , PathBuf } ;
@@ -16,12 +14,6 @@ use terminal_size::{terminal_size, Width};
1614pub struct Commands ( pub Vec < Command > ) ;
1715#[ derive( Debug , Clone ) ]
1816pub enum Command {
19- Call {
20- canister : String ,
21- method : String ,
22- args : Vec < Value > ,
23- encode_only : bool ,
24- } ,
2517 Config ( String ) ,
2618 Show ( Value ) ,
2719 Let ( String , Value ) ,
@@ -41,54 +33,6 @@ pub enum BinOp {
4133impl Command {
4234 pub fn run ( self , helper : & mut MyHelper ) -> anyhow:: Result < ( ) > {
4335 match self {
44- Command :: Call {
45- canister,
46- method,
47- args,
48- encode_only,
49- } => {
50- let try_id = Principal :: from_text ( & canister) ;
51- let canister_id = match try_id {
52- Ok ( ref id) => id,
53- Err ( _) => match helper. env . 0 . get ( & canister) {
54- Some ( IDLValue :: Principal ( id) ) => id,
55- _ => return Err ( anyhow ! ( "{} is not a canister id" , canister) ) ,
56- } ,
57- } ;
58- let agent = & helper. agent ;
59- let mut map = helper. canister_map . borrow_mut ( ) ;
60- let info = map. get ( & agent, & canister_id) ?;
61- let func = info
62- . methods
63- . get ( & method)
64- . ok_or_else ( || anyhow ! ( "no method {}" , method) ) ?;
65- let mut values = Vec :: new ( ) ;
66- for arg in args. into_iter ( ) {
67- values. push ( arg. eval ( & helper) ?) ;
68- }
69- let args = IDLArgs { args : values } ;
70- if encode_only {
71- let bytes = args. to_bytes_with_types ( & info. env , & func. args ) ?;
72- let res = IDLValue :: Vec ( bytes. into_iter ( ) . map ( IDLValue :: Nat8 ) . collect ( ) ) ;
73- println ! ( "{}" , res) ;
74- helper. env . 0 . insert ( "_" . to_string ( ) , res) ;
75- return Ok ( ( ) ) ;
76- }
77- let time = Instant :: now ( ) ;
78- let res = call ( & agent, & canister_id, & method, & args, & info. env , & func) ?;
79- let duration = time. elapsed ( ) ;
80- println ! ( "{}" , res) ;
81- let width = if let Some ( ( Width ( w) , _) ) = terminal_size ( ) {
82- w as usize
83- } else {
84- 80
85- } ;
86- println ! ( "{:>width$}" , format!( "({:.2?})" , duration) , width = width) ;
87- // TODO multiple values
88- for arg in res. args . into_iter ( ) {
89- helper. env . 0 . insert ( "_" . to_string ( ) , arg) ;
90- }
91- }
9236 Command :: Import ( id, canister_id, did) => {
9337 if let Some ( did) = & did {
9438 let path = resolve_path ( & helper. base_path , did) ;
@@ -130,8 +74,17 @@ impl Command {
13074 }
13175 Command :: Config ( conf) => helper. config = Configs :: from_dhall ( & conf) ?,
13276 Command :: Show ( val) => {
77+ let time = Instant :: now ( ) ;
13378 let v = val. eval ( & helper) ?;
79+ let duration = time. elapsed ( ) ;
13480 println ! ( "{}" , v) ;
81+ helper. env . 0 . insert ( "_" . to_string ( ) , v) ;
82+ let width = if let Some ( ( Width ( w) , _) ) = terminal_size ( ) {
83+ w as usize
84+ } else {
85+ 80
86+ } ;
87+ println ! ( "{:>width$}" , format!( "({:.2?})" , duration) , width = width) ;
13588 }
13689 Command :: Identity ( id, opt_pem) => {
13790 use ic_agent:: Identity ;
@@ -216,38 +169,6 @@ impl std::str::FromStr for Commands {
216169 }
217170}
218171
219- #[ tokio:: main]
220- async fn call (
221- agent : & Agent ,
222- canister_id : & Principal ,
223- method : & str ,
224- args : & IDLArgs ,
225- env : & TypeEnv ,
226- func : & Function ,
227- ) -> anyhow:: Result < IDLArgs > {
228- let args = args. to_bytes_with_types ( env, & func. args ) ?;
229- let bytes = if func. is_query ( ) {
230- agent
231- . query ( canister_id, method)
232- . with_arg ( args)
233- . with_effective_canister_id ( canister_id. clone ( ) )
234- . call ( )
235- . await ?
236- } else {
237- let waiter = delay:: Delay :: builder ( )
238- . exponential_backoff ( std:: time:: Duration :: from_secs ( 1 ) , 1.1 )
239- . timeout ( std:: time:: Duration :: from_secs ( 60 * 5 ) )
240- . build ( ) ;
241- agent
242- . update ( canister_id, method)
243- . with_arg ( args)
244- . with_effective_canister_id ( canister_id. clone ( ) )
245- . call_and_wait ( waiter)
246- . await ?
247- } ;
248- Ok ( IDLArgs :: from_bytes_with_types ( & bytes, env, & func. rets ) ?)
249- }
250-
251172pub fn resolve_path ( base : & Path , file : & str ) -> PathBuf {
252173 let file = PathBuf :: from ( shellexpand:: tilde ( file) . into_owned ( ) ) ;
253174 if file. is_absolute ( ) {
0 commit comments