Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
chenyan-dfinity committed Aug 25, 2023
1 parent 65220e4 commit 8bd706f
Show file tree
Hide file tree
Showing 14 changed files with 207 additions and 192 deletions.
51 changes: 35 additions & 16 deletions rust/candid/src/bindings/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ fn pp_function<'a>(config: &Config, id: &'a str, func: &'a Function) -> RcDoc<'a
let empty = BTreeSet::new();
let arg_prefix = str(match config.target {
Target::CanisterCall => "&self",
Target::Agent => "&self, agent: &ic_agent::Agent",
Target::Agent => "&self",
Target::CanisterStub => unimplemented!(),
});
let args = concat(
Expand Down Expand Up @@ -337,20 +337,16 @@ fn pp_function<'a>(config: &Config, id: &'a str, func: &'a Function) -> RcDoc<'a
(0..func.args.len()).map(|i| RcDoc::text(format!("&arg{i}"))),
RcDoc::text(", "),
);
let blob = str("Encode!").append(enclose(
"(",
args,
").map_err(|e| ic_agent::AgentError::CandidError(e.into()))?;",
));
let blob = str("Encode!").append(enclose("(", args, ")?;"));
let rets = RcDoc::concat(
func.rets
.iter()
.map(|ty| str(", ").append(pp_ty(ty, &empty))),
);
str("let args = ").append(blob).append(RcDoc::hardline())
.append(format!("let bytes = agent.{builder_method}(&self.0, \"{method}\").with_arg(args).{call}().await?;"))
.append(format!("let bytes = self.1.{builder_method}(&self.0, \"{method}\").with_arg(args).{call}().await?;"))
.append(RcDoc::hardline())
.append("Decode!(&bytes").append(rets).append(").map_err(|e| ic_agent::AgentError::CandidError(e.into()))")
.append("Ok(Decode!(&bytes").append(rets).append(")?)")
}
Target::CanisterStub => unimplemented!(),
};
Expand All @@ -367,9 +363,23 @@ fn pp_actor<'a>(config: &'a Config, env: &'a TypeEnv, actor: &'a Type) -> RcDoc<
}),
RcDoc::hardline(),
);
let res = RcDoc::text("pub struct SERVICE(pub Principal);")
let struct_name = config.service_name.to_case(Case::Pascal);
let service_def = match config.target {
Target::CanisterCall => format!("pub struct {}(pub Principal);", struct_name),
Target::Agent => format!(
"pub struct {}<'a>(pub Principal, pub &'a ic_agent::Agent);",
struct_name
),
Target::CanisterStub => unimplemented!(),
};
let service_impl = match config.target {
Target::CanisterCall => format!("impl {} ", struct_name),
Target::Agent => format!("impl<'a> {}<'a> ", struct_name),
Target::CanisterStub => unimplemented!(),
};
let res = RcDoc::text(service_def)
.append(RcDoc::hardline())
.append("impl SERVICE ")
.append(service_impl)
.append(enclose_space("{", body, "}"))
.append(RcDoc::hardline());
if let Some(cid) = config.canister_id {
Expand All @@ -379,10 +389,19 @@ fn pp_actor<'a>(config: &'a Config, env: &'a TypeEnv, actor: &'a Type) -> RcDoc<
.map(|b| b.to_string())
.collect::<Vec<_>>()
.join(", ");
res.append(format!(
r#"pub const {}: SERVICE = SERVICE(Principal::from_slice(&[{}])); // {}"#,
config.service_name, slice, cid
))
let id = RcDoc::text(format!(
"pub const CANISTER_ID : Principal = Principal::from_slice(&[{}]); // {}",
slice, cid
));
let instance = match config.target {
Target::CanisterCall => format!(
"pub const {} : {} = {}(CANISTER_ID);",
config.service_name, struct_name, struct_name
),
Target::Agent => "".to_string(),
Target::CanisterStub => unimplemented!(),
};
res.append(id).append(RcDoc::hardline()).append(instance)
} else {
res
}
Expand All @@ -392,15 +411,15 @@ pub fn compile(config: &Config, env: &TypeEnv, actor: &Option<Type>) -> String {
let header = format!(
r#"// This is an experimental feature to generate Rust binding from Candid.
// You may want to manually adjust some of the types.
#![allow(dead_code)]
#![allow(dead_code, unused_imports)]
use {}::{{self, CandidType, Deserialize, Principal, Encode, Decode}};
"#,
config.candid_crate
);
let header = header
+ match &config.target {
Target::CanisterCall => "use ic_cdk::api::call::CallResult as Result;\n",
Target::Agent => "type Result<T> = std::result::Result<T, ic_agent::AgentError>;",
Target::Agent => "type Result<T> = std::result::Result<T, ic_agent::AgentError>;\n",
Target::CanisterStub => "",
};
let (env, actor) = nominalize_all(env, actor);
Expand Down
10 changes: 6 additions & 4 deletions rust/candid/tests/assets/ok/actor.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// This is an experimental feature to generate Rust binding from Candid.
// You may want to manually adjust some of the types.
use candid::{self, CandidType, Deserialize, Principal};
#![allow(dead_code, unused_imports)]
use candid::{self, CandidType, Deserialize, Principal, Encode, Decode};
use ic_cdk::api::call::CallResult as Result;

candid::define_function!(pub F : (i8) -> (i8));
Expand All @@ -9,8 +10,8 @@ pub type G = F;
#[derive(CandidType, Deserialize)]
pub struct O(Option<Box<O>>);

pub struct SERVICE(pub Principal);
impl SERVICE {
pub struct Service(pub Principal);
impl Service {
pub async fn f(&self, arg0: candid::Nat) -> Result<(H,)> {
ic_cdk::call(self.0, "f", (arg0,)).await
}
Expand All @@ -24,4 +25,5 @@ impl SERVICE {
ic_cdk::call(self.0, "o", (arg0,)).await
}
}
pub const service: SERVICE = SERVICE(Principal::from_slice(&[])); // aaaaa-aa
pub const CANISTER_ID : Principal = Principal::from_slice(&[]); // aaaaa-aa
pub const service : Service = Service(CANISTER_ID);
10 changes: 6 additions & 4 deletions rust/candid/tests/assets/ok/class.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
// This is an experimental feature to generate Rust binding from Candid.
// You may want to manually adjust some of the types.
use candid::{self, CandidType, Deserialize, Principal};
#![allow(dead_code, unused_imports)]
use candid::{self, CandidType, Deserialize, Principal, Encode, Decode};
use ic_cdk::api::call::CallResult as Result;

#[derive(CandidType, Deserialize)]
pub struct List(Option<(candid::Int,Box<List>,)>);

pub struct SERVICE(pub Principal);
impl SERVICE {
pub struct Service(pub Principal);
impl Service {
pub async fn get(&self) -> Result<(List,)> {
ic_cdk::call(self.0, "get", ()).await
}
pub async fn set(&self, arg0: List) -> Result<(List,)> {
ic_cdk::call(self.0, "set", (arg0,)).await
}
}
pub const service: SERVICE = SERVICE(Principal::from_slice(&[])); // aaaaa-aa
pub const CANISTER_ID : Principal = Principal::from_slice(&[]); // aaaaa-aa
pub const service : Service = Service(CANISTER_ID);
3 changes: 2 additions & 1 deletion rust/candid/tests/assets/ok/comment.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// This is an experimental feature to generate Rust binding from Candid.
// You may want to manually adjust some of the types.
use candid::{self, CandidType, Deserialize, Principal};
#![allow(dead_code, unused_imports)]
use candid::{self, CandidType, Deserialize, Principal, Encode, Decode};
use ic_cdk::api::call::CallResult as Result;

pub type Id = u8;
Expand Down
10 changes: 6 additions & 4 deletions rust/candid/tests/assets/ok/cyclic.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// This is an experimental feature to generate Rust binding from Candid.
// You may want to manually adjust some of the types.
use candid::{self, CandidType, Deserialize, Principal};
#![allow(dead_code, unused_imports)]
use candid::{self, CandidType, Deserialize, Principal, Encode, Decode};
use ic_cdk::api::call::CallResult as Result;

pub type C = Box<A>;
Expand All @@ -11,8 +12,8 @@ pub struct A(Option<B>);
pub type Z = Box<A>;
pub type Y = Z;
pub type X = Y;
pub struct SERVICE(pub Principal);
impl SERVICE {
pub struct Service(pub Principal);
impl Service {
pub async fn f(
&self,
arg0: A,
Expand All @@ -25,4 +26,5 @@ impl SERVICE {
ic_cdk::call(self.0, "f", (arg0,arg1,arg2,arg3,arg4,arg5,)).await
}
}
pub const service: SERVICE = SERVICE(Principal::from_slice(&[])); // aaaaa-aa
pub const CANISTER_ID : Principal = Principal::from_slice(&[]); // aaaaa-aa
pub const service : Service = Service(CANISTER_ID);
10 changes: 6 additions & 4 deletions rust/candid/tests/assets/ok/escape.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// This is an experimental feature to generate Rust binding from Candid.
// You may want to manually adjust some of the types.
use candid::{self, CandidType, Deserialize, Principal};
#![allow(dead_code, unused_imports)]
use candid::{self, CandidType, Deserialize, Principal, Encode, Decode};
use ic_cdk::api::call::CallResult as Result;

#[derive(CandidType, Deserialize)]
Expand All @@ -15,10 +16,11 @@ pub struct T {
_1020746185_: candid::Nat,
}

pub struct SERVICE(pub Principal);
impl SERVICE {
pub struct Service(pub Principal);
impl Service {
pub async fn _2635468193_(&self, arg0: T) -> Result<()> {
ic_cdk::call(self.0, "\n\'\"\'\'\"\"\r\t", (arg0,)).await
}
}
pub const service: SERVICE = SERVICE(Principal::from_slice(&[])); // aaaaa-aa
pub const CANISTER_ID : Principal = Principal::from_slice(&[]); // aaaaa-aa
pub const service : Service = Service(CANISTER_ID);
10 changes: 6 additions & 4 deletions rust/candid/tests/assets/ok/example.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// This is an experimental feature to generate Rust binding from Candid.
// You may want to manually adjust some of the types.
use candid::{self, CandidType, Deserialize, Principal};
#![allow(dead_code, unused_imports)]
use candid::{self, CandidType, Deserialize, Principal, Encode, Decode};
use ic_cdk::api::call::CallResult as Result;

#[derive(CandidType, Deserialize)]
Expand Down Expand Up @@ -57,8 +58,8 @@ pub struct B (candid::Int,candid::Nat,);
#[derive(CandidType, Deserialize)]
pub enum A { #[serde(rename="a")] A, #[serde(rename="b")] B(B) }

pub struct SERVICE(pub Principal);
impl SERVICE {
pub struct Service(pub Principal);
impl Service {
pub async fn f(
&self,
arg0: List,
Expand Down Expand Up @@ -87,4 +88,5 @@ impl SERVICE {
ic_cdk::call(self.0, "x", (arg0,arg1,)).await
}
}
pub const service: SERVICE = SERVICE(Principal::from_slice(&[])); // aaaaa-aa
pub const CANISTER_ID : Principal = Principal::from_slice(&[]); // aaaaa-aa
pub const service : Service = Service(CANISTER_ID);
10 changes: 6 additions & 4 deletions rust/candid/tests/assets/ok/fieldnat.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// This is an experimental feature to generate Rust binding from Candid.
// You may want to manually adjust some of the types.
use candid::{self, CandidType, Deserialize, Principal};
#![allow(dead_code, unused_imports)]
use candid::{self, CandidType, Deserialize, Principal, Encode, Decode};
use ic_cdk::api::call::CallResult as Result;

#[derive(CandidType, Deserialize)]
Expand Down Expand Up @@ -30,8 +31,8 @@ pub struct FooArg { _2_: candid::Int }
#[derive(CandidType, Deserialize)]
pub struct FooRet { _2_: candid::Int, _2: candid::Int }

pub struct SERVICE(pub Principal);
impl SERVICE {
pub struct Service(pub Principal);
impl Service {
pub async fn bab(&self, arg0: candid::Int, arg1: candid::Nat) -> Result<()> {
ic_cdk::call(self.0, "bab", (arg0,arg1,)).await
}
Expand All @@ -54,4 +55,5 @@ impl SERVICE {
ic_cdk::call(self.0, "foo", (arg0,)).await
}
}
pub const service: SERVICE = SERVICE(Principal::from_slice(&[])); // aaaaa-aa
pub const CANISTER_ID : Principal = Principal::from_slice(&[]); // aaaaa-aa
pub const service : Service = Service(CANISTER_ID);
16 changes: 9 additions & 7 deletions rust/candid/tests/assets/ok/keyword.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// This is an experimental feature to generate Rust binding from Candid.
// You may want to manually adjust some of the types.
use candid::{self, CandidType, Deserialize, Principal};
#![allow(dead_code, unused_imports)]
use candid::{self, CandidType, Deserialize, Principal, Encode, Decode};
use ic_cdk::api::call::CallResult as Result;

#[derive(CandidType, Deserialize)]
Expand Down Expand Up @@ -48,12 +49,12 @@ candid::define_function!(pub T : (Return) -> ());
#[derive(CandidType, Deserialize)]
pub enum VariantArg { A, B, C, D(f64) }

pub struct SERVICE(pub Principal);
impl SERVICE {
pub async fn Oneway(&self) -> Result<()> {
pub struct Service(pub Principal);
impl Service {
pub async fn oneway(&self) -> Result<()> {
ic_cdk::call(self.0, "Oneway", ()).await
}
pub async fn f_(&self, arg0: O) -> Result<(O,)> {
pub async fn f(&self, arg0: O) -> Result<(O,)> {
ic_cdk::call(self.0, "f_", (arg0,)).await
}
pub async fn field(&self, arg0: FieldArg) -> Result<(FieldRet,)> {
Expand All @@ -65,7 +66,7 @@ impl SERVICE {
pub async fn oneway(&self, arg0: u8) -> Result<()> {
ic_cdk::call(self.0, "oneway", (arg0,)).await
}
pub async fn oneway_(&self, arg0: u8) -> Result<()> {
pub async fn oneway(&self, arg0: u8) -> Result<()> {
ic_cdk::call(self.0, "oneway_", (arg0,)).await
}
pub async fn query(&self, arg0: serde_bytes::ByteBuf) -> Result<
Expand All @@ -87,4 +88,5 @@ impl SERVICE {
ic_cdk::call(self.0, "variant", (arg0,)).await
}
}
pub const service: SERVICE = SERVICE(Principal::from_slice(&[])); // aaaaa-aa
pub const CANISTER_ID : Principal = Principal::from_slice(&[]); // aaaaa-aa
pub const service : Service = Service(CANISTER_ID);
Loading

0 comments on commit 8bd706f

Please sign in to comment.