#I have difficulties understanding rust docs.

44 messages · Page 1 of 1 (latest)

unique lance
#

Just trying to use this package here https://docs.rs/ic-cdk/latest/ic_cdk/api/call/fn.call.html but I got way too many errors with it.
This is my first time using async with let v = futures::executor::block_on(example());
https://gist.github.com/rust-play/c6e3b5c305e571d459ef392e64efeafc

So, After implementing this just like the docs says I got this wired error

[E0277]: the trait bound `for<'a> std::string::String: ArgumentDecoder<'a>` is not satisfied
   --> frontend/src/main.rs:28:103
    |
28  | ..., String)> = ic_cdk::api::call::call(principal, "greet", ("Ali".to_string(), )).await;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ArgumentDecoder<'a>` is not implemented for `std::string::String`
    |
    = help: the following other types implement trait `ArgumentDecoder<'a>`:
              ()
              (A, B)
              (A, B, C)
              (A, B, C, D)
              (A, B, C, D, E)
              (A, B, C, D, E, F)
              (A, B, C, D, E, F, G)
              (A, B, C, D, E, F, G, H)
            and 9 others
unique lance
light bolt
#

no, what does "implementing this just like the docs says" mean?

unique lance
#

So I did the same

light bolt
#

there is no example there

#

and the api is really weird

#

writing ic_cdk::api::call::CallResult<(String,)> should work

unique lance
#

Yeah 🥹

light bolt
#

either that or the docs would be outdated

#

which happens

#

but not this time

unique lance
#

I was thinking maybe I didn’t understand the docs cuz I am new to rust

light bolt
#

yeah the only thing was the ArgumentDecoder bound on R

#

ah I see why it's not implemented for String

#

because it is on (A, B) etc.

#

eh

#

still weird

#

btw (String,) is a 1-element tuple

unique lance
#

Oh, the ArgumentDecoder and ArgumentEncider Was confusing as well

light bolt
#

the second generic parameter of fn call

unique lance
#

Aha if it is generic instead of <R> i can say <String>

light bolt
#

yeah kind of

unique lance
#

one more help please

let greeting: ic_cdk::api::call::CallResult<&str, (ic_cdk::api::call::RejectionCode, &str)> = ic_cdk::api::call::call(principal, "greet", ("Ali", "")).await;

I removed the type here ic_cdk::api::call::CallResult<&str, (ic_cdk::api::call::RejectionCode, &str)>

let greeting = ic_cdk::api::call::call(principal, "greet", ("Ali", "")).await;

Now it cannot infer the type R
However here is my mistake
the output are not CallResult but it is impl Future<Output = CallResult<R>>

#
error[E0698]: type inside `async fn` body must be known in this context
  --> frontend/src/main.rs:26:20
   |
26 |     let greeting = ic_cdk::api::call::call(principal, "greet", ("Ali", "")).await;
   |                    ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `R` declared on the function `call`

light bolt
#

once you call await you get the Output

unique lance
#

yeah

#

I should

light bolt
#

you can specify R with call::<_, (&str,)>(principal, ...).await;

#

although that won't work

#

because you need String instead

unique lance
#

Aha
what about somthing like

let greeting: Future<Output = CallResult<String>> = ic_cdk::api::call::call(principal, "greet", ("Ali", "")).await;

so it infer R as String

light bolt
#

you can't write that in rust

unique lance
#

so how can I tell rust R is String

light bolt
#

also impl Future "disappears" when you call await

light bolt
light bolt
#

I told you how to specify it without that

#

call::<_, (String,)>(principal, ...).await;

#

if you use it later with something that expects that type you don't have to specify that at all