Automatic generation of Candid from Rust

Has there been any progress on this since this was last asked?

This response by @chenyan has the last update that this was something being worked on.

The documentation here references this but wasn’t able to figure out how to set this up exactly

I also found these 2 pull requests that pertain to this discussion but haven’t been able to completely work out how to make this work


Any updates/thoughts?


Hey yeah we’ve been able to generate candid from rust for a while now. Not sure why it’s still kinda hidden from documentation. All the psychedelic projects use it ! You just need to add the CandidType derive, and the
candid_service(query/update/init) macro to all the methods and types that need to be exported. Then, the export_service!() macro will generate function that returns the candid from rust, which can be run differently depending on the project setup

For projects using a You can add a main function only run when target is not wasm32. Then, running cargo run would print the candid, which can be easily piped to a file (cargo run > candid.did ). This works well with mono canister architechtures.
Example: nft-marketplace/ at develop · Psychedelic/nft-marketplace · GitHub

for projects using cdylib/ You can make a rust test called save_candid, which would save the candid to a file in the project root when running cargo test. This works really well for multi canister architectures.
Example: cap/ at main · Psychedelic/cap · GitHub

Personally, I’ve been moving solely to the test flow, to allow exporting multiple canisters did interfaces with a single command. If you have other tests as well, you can run only the candid tests using cargo test save_candid

We also plan on making this easy and automatic with the ic_kit - Rust, where we’d include the corresponding candid_method with the #[update/query/init] macro automatically


Thank you so much for the response.

With the mechanism that uses the test to generate the .did file, what is the value of CARGO_MANIFEST_DIR that you are passing in the code highlighted here?

1 Like

Of course! Having auto generation makes work so much easier.

The cargo manifest dir is a environment variable provided (by cargo) during the test run, of the location of the crates cargo.toml. This is the crate toml, not the workspace, so we step back 2 parent directories to the project root, and place the candid in the candid/<name>.did

1 Like

Right, I was asking what exact value you were passing.

I ended up shortening it further by doing it like this instead of relying on the env variable

1 Like

Sorry, I had meant to add (but somehow didn’t) that it’s provided automatically by cargo

This is a good solution as well!

1 Like

@chenyan It would sure be nice to not have to do these workarounds to get that file generated. I’d love dfx to do it for you

@oss so I assume you need to pass in the path to the generated Candid file in dfx.json? So for example, cargo test needs to run before installing the Wasm binary?

@lastmjs Exactly, I usually like having the step automatically done through a makefile (make build does the candid gen, then the dfx build).

Separately, we’re finding a solution with the kit to tie this all together. In 0.5, query/update/init macros automatically use the candid_method, as well as the candid being exported with a single macro at the end of your file. Ideally we’re looking for a solution to just do everything on compile, but already the process is 10x better

1 Like