我需要在String
的内容中调用通用方法,该方法来自FFI调用者,而不是代码中的静态&str
:
match endpoint.as_ref() {
"documents" => get_objs_as_json::<Document, JsonDocument>(db_url, sql),
"theme_links" => get_objs_as_json::<ThemeLink, JsonThemeLink>(db_url, sql),
"dressing_links" => get_objs_as_json::<DressingLink, JsonDressingLink>(db_url, sql),
"dressing_configurations" => {
get_objs_as_json::<DressingConfiguration, JsonDressingConfiguration>(db_url, sql)
}
&_ => Err(BackendError::InvalidArgument(endpoint)),
}
它正在工作,但确实很丑陋,我需要为我拥有的每个通用方法执行此操作……
我试图制作一个endpoint => (InputStruct, OutputStruct)
这样的哈希图,但是我无法存储和使用类似的类型。
也许我可以使用宏来做到这一点,但是我不知道如何将字符串参数转换为宏中的类型。
编辑 好的,尝试重新制定。 我有一个通用方法,可以从结构类型上获取数据库中的数据,然后将其转换为其他结构。但是我的调用者不知道这些结构的名称,因此我需要包装器将任意字符串转换为几种类型。 这里的想法是替换(就像在C宏中一样,即使我知道Rust宏也不一样)
get_and_convert("documents", params)
作者
get_and_convert<Document, JsonDocument>(params)
因为“ documents”参数来自FFI,所以调用者不知道rust内部,也无法调用泛型方法。
如:
pub struct Document {
pub a: i32,
}
pub struct JsonDocument {
pub a: i32,
}
impl JsonDocument {
pub fn to_json(&self) -> String {
// …
}
}
impl From<Document> for JsonDocument {
fn from(input: Input) -> Self {
Output {
a: input.a
}
}
}
pub fn get_and_convert<I, O>(db_params: String) -> String {
let input = get_data(db_params);
let output = input.into();
output.to_json()
}
所以我尝试了类似的事情(我是宏的新手,所以代码非常错误,更像是伪代码来阅读它):
macro_rules! get_types {
("documents") => {
(Document, JsonDocument)
};
("themes") => {
(Theme, JsonTheme)
};
}
macro_rules! get_objs {
($x:expr, $y:expr, $params:expr) => {
get_and_convert::<$x, $y>($params)
};
}
使用方式:
pub fn testmacro(args: String) {
let (input_type, output_type) = get_types!("documents");
let result = get_objs!(input_type, output_type, args);
}