如果我没有恰当地问这个问题,我道歉。我觉得问题的一部分是我很难用习惯用语来描述我正在做的事情。
我目前正试图弄清楚我是否可以注册在lib.rs
中定义的处理程序函数到服务中,仅基于读取YAML清单文件。
我有一个清单文件config.yaml
event: count
handler: count_handler
我有一个lib.rs
与以下定义:
// This is somewhat pseudo-code (has not been tested, but gives you the idea)
fn count_handler(d: Vec<u8>) -> Vec<u8> {
println!("count_handler was called!");
Vec::new()
}
type HandlerFn = fn(Vec<u8>) -> Vec<u8>;
struct Service {
handlers: HashMap<String, HandlerFn>,
}
impl Service {
fn new() -> Self {
let handlers: HashMap::new();
Self { handlers }
}
fn register_handler(&mut self, name: String, handler: HandlerFn) {
self.handlers.insert(name, handler);
}
fn start() {
println!("I'm doing some things with these handlers: {:?}", self.handlers);
}
}
我想弄明白的是:
是否有任何方法可以使用仅清单文件在Service
中自动注册我的count_handler
?- 更新:似乎没有办法做到这一点使用只有manifest文件,所以让我进一步澄清
- 是否有办法使用某种类型的宏来做到这一点?(proc宏?)
- 我基本上需要任何映射生成发生而不需要用户手动注册处理程序。
理想情况下,我将能够做到以下几点:
fn main() {
let manifest: Manifest = Manifest::from_file("config.yaml");
// assert_eq!(manifest.event, "count".to_owned());
// assert_eq!(manifest.handler, "count_handler".to_owned());
let service = Service::new();
service.start();
// "I'm doing some things with these handlers: HashMap{ "count": Function(count_handler) }"
}
一些约束和说明:
- 假设清单中定义的
handler
总是存在于lib.rs
count_handler
可以是任何满足HandlerFn
的函数- 清单中的
handler
将始终由event
在Service
中索引- 在本例中,
<"count", count_handler()>
在Service
中注册。
- 在本例中,
我不认为这在Rust中是可能的,但只是想弄清楚一些。
如果您想在运行时处理此问题,即在更改YAML文件时不重新编译应用程序,那么答案是:不,这是不可能的(不用再费力了)。这是因为Rust没有运行时反射的概念,因此函数的名称在编译时被擦除。根本没有办法查到。
作为用户EvilTak在评论中指出,你可以建立一个支持结构,这样你最终得到的某种从处理程序映射函数名(例如count_handler
)对函数的引用可以在运行时调用,所以例如HashMap<String, fn(Vec<u8>) -> Vec<u8>>
。
然而,这似乎不符合您的"只使用清单文件"的标准。
也就是说,如果每次更改YAML文件时都可以重新编译应用程序,那么这是非常可能的。接下来的想法是在编译期间,在宏中读取YAML文件,并生成代码,如果您手动连接东西,您将自己编写这些代码。