Skip to main content

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}