Member-only story

Automatic Candid Generation in Rust: Exploring the ic_cdk v0.10.0 Update

David Dal Busco
5 min readJul 21, 2023

Photo by Bilal O. on Unsplash

So, yesterday I upgraded Juno to the latest release of ic_cdk and discovered that the automatic generation of the Candid declarations needed an update. In this post, I will walk you through the process of migrating your project.

Update: On September 18th, 2023, a new version of the ic_cdk v0.11.0 has been released, and this article has been updated accordingly.

Previous Workaround

If you have previously relied on automatic type generation, chances are you used the export_service crate and the workaround involving generating and writing the did files to the file system through a test by running cargo test .

I covered this approach in a previous blog post earlier this year, but to summarize, your code most probably looked like the following:

use ic_cdk_macros::{query, update};
use ic_cdk::export::candid::{candid_method};
use ic_cdk::export::candid::{export_service};

// Your code

#[candid_method(query)]
#[query]
fn hello(name: String) -> String {
format!("Hello, {}!", name)
}

#[candid_method(update)]
#[update]
fn world(name: String) -> String {
format!("World, {}!", name)
}

// The workaround to generate did files automatically

fn export_candid() -> String {
export_service!();
__export_service()
}

#[cfg(test)]
mod tests {
use super::export_candid;

#[test]
fn save_candid() {
use std::env;
use std::fs::write;
use std::path::PathBuf;

let dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let dir = dir
.parent()
.unwrap()
.parent()
.unwrap()
.join("src")
.join("demo");
write(dir.join("demo.did"), export_candid()).expect("Write failed.");
}
}

New Solution

No more workarounds! ic_cdk v0.10.0 introduces a new macro called export_candid, designed specifically to facilitate automatic generation of the did files.

Therefore, if you are migrating or starting a new canister and want to generate the types automatically, the new solution basically consists of adding export_candid!() at the end of lib.rs, and that's all you need for the code.

David Dal Busco
David Dal Busco

Written by David Dal Busco

Freelancer by day | Creator of Juno.build by night

No responses yet

Write a response