Мне нужно вызвать универсальный метод в содержимом 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)
, но я не могу хранить и использовать такие типы.
Возможно, я могу сделать это с помощью макроса, но я не знаю, как преобразовать строковый параметр в типы в макросе.
EDIT Хорошо, пытаясь переформулировать.У меня есть универсальный метод, который получает данные в моей базе данных по типу структуры, а затем преобразовывает их в какую-то другую структуру.Но мой вызывающий не знает названия структур, поэтому мне нужна оболочка для преобразования произвольной строки в пару типов.Идея здесь состоит в том, чтобы заменить (как в макросе C, даже если я знаю, что макросы Rust отличаются)
get_and_convert("documents", params)
на
get_and_convert<Document, JsonDocument>(params)
Это потому, что параметр "documents" приходитиз FFI вызывающая сторона не знает внутреннюю ржавчину и не может вызвать универсальный метод.
как в:
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);
}