Hi, I’m trying to build a crate in Rust that offers features which can be easily integrated by developers. While implementing the Rust part only took about 5 minutes to validate, I’ve been struggling for a day with the Candid generation part because I obviously want developer to be able to generate their did files automatically. Does anyone have any suggestions on how I can accomplish this?
For example, let’s consider a crate (“lib”) like the following:
use ic_cdk::{query};
use candid::{CandidType};
use serde::Deserialize;
#[derive(CandidType, Deserialize)]
pub struct Demo {
pub text: String,
}
#[query]
pub fn hello() -> Demo {
Demo {
text: "world".to_string()
}
}
#[macro_export]
macro_rules! include_lib {
() => {
use lib::{hello};
};
}
I want developers to easily integrate these features and extend them with their own code. This is achieved as follows:
use ic_cdk::{export_candid, query};
use lib::{Demo, include_lib};
#[query]
fn greet(name: String) -> Demo {
Demo {
text: format!("Hello, {}!", name)
}
}
include_lib!();
export_candid!();
However, the issue arises with the generated DID file. While the WASM is completely fine, the DID file only contains the additional functions defined in the consumer:
type Demo = record { "text" : text };
service : { greet : (text) -> (Demo) query }
This is not what I want. Ideally, I would like to automatically generate a DID service that includes both, for example:
service : {
greet : (text) -> (Demo) query;
hello : () -> (Demo) query;
}
Yesterday, I opened a question asking if there’s a way to make export_candid
support this, but I understand it’s not possible (see thread).
Then, I considered importing DID files, which is indeed possible (see thread). However, the issue here is that both DID files contain similar types, leading didc
to fail due to duplication (see thread).
In short, it feels like I’ve hit a series of dead ends. Does anyone have any innovative ideas?