cordis_include/resolver.rs
1//! Plugin name resolution contract, implemented by the loader layer.
2
3use cordis::{CordisError, ErrorCode, PluginHandle};
4
5/// Maps entry names to reusable plugin handles.
6///
7/// This is the Rust replacement for upstream Cordis' dynamic
8/// `import(name)`: resolution is static and injectable. The default
9/// implementation in `cordis-loader` is a registry populated at startup;
10/// tests and embedders can supply their own (plain closures implement the
11/// trait too).
12///
13/// The trait returns [`PluginHandle`] — not a bare plugin — because the
14/// handle's stable `PluginKey` identity is what fibers, events, and "did
15/// this plugin dispose itself?" checks key off. Resolving the same name
16/// twice must yield distinct handles (wrap the plugin each time, as
17/// `PluginHandle::new` does), mirroring one plugin instance per entry.
18pub trait PluginResolver: Send + Sync + 'static {
19 /// Resolve an entry's plugin name to a fresh handle.
20 fn resolve(&self, name: &str) -> cordis::Result<PluginHandle>;
21}
22
23impl<F> PluginResolver for F
24where
25 F: Fn(&str) -> cordis::Result<PluginHandle> + Send + Sync + 'static,
26{
27 fn resolve(&self, name: &str) -> cordis::Result<PluginHandle> {
28 self(name)
29 }
30}
31
32/// The error returned for a name no resolver knows about.
33pub fn unknown_plugin(name: &str) -> CordisError {
34 CordisError::with_message(
35 ErrorCode::MissingService,
36 format!("no plugin registered under the name `{name}`"),
37 )
38}