Skip to content

fidius-host::host Rust

PluginHost builder and plugin discovery.

Structs

fidius-host::host::PluginHost

pub

Host for loading and managing plugins.

Fields

Name Type Description
search_paths Vec < PathBuf >
load_policy LoadPolicy
require_signature bool
trusted_keys Vec < VerifyingKey >
expected_hash Option < u64 >
expected_strategy Option < BufferStrategyKind >
egress Option < Arc < dyn crate :: executor :: wasm :: EgressPolicy > > Host-wide default wasi:http egress policy (FIDIUS-I-0027). Applied to
every load_wasm; load_wasm_with_egress overrides it per plugin. None
→ no egress (a guest importing wasi:http fails closed at load).

Methods

builder pub
fn builder () -> PluginHostBuilder

Create a new builder.

Source
    pub fn builder() -> PluginHostBuilder {
        PluginHostBuilder::new()
    }
discover pub
fn discover (& self) -> Result < Vec < PluginInfo > , LoadError >

Discover all valid plugins in the configured search paths.

Scans each path for both: - dylib files (cdylib plugins, the existing path), and - subdirectories containing a package.toml with runtime = "python" (when the python feature is enabled). Returns owned PluginInfo for every valid plugin found, with PluginInfo::runtime distinguishing the two kinds.

Source
    pub fn discover(&self) -> Result<Vec<PluginInfo>, LoadError> {
        #[cfg(feature = "tracing")]
        tracing::info!(search_paths = ?self.search_paths, "discovering plugins");

        let mut plugins = Vec::new();

        for search_path in &self.search_paths {
            if !search_path.is_dir() {
                continue;
            }

            let entries = std::fs::read_dir(search_path)?;
            for entry in entries {
                let entry = entry?;
                let path = entry.path();

                if is_dylib(&path) {
                    self.discover_cdylib(&path, &mut plugins);
                } else if path.is_dir() && path.join("package.toml").exists() {
                    self.discover_package(&path, &mut plugins);
                }
            }
        }

        Ok(plugins)
    }
discover_cdylib private
fn discover_cdylib (& self , path : & Path , plugins : & mut Vec < PluginInfo >)
Source
    fn discover_cdylib(&self, path: &Path, plugins: &mut Vec<PluginInfo>) {
        // Verify signature before dlopen to prevent code execution from untrusted dylibs
        if self.require_signature && signing::verify_signature(path, &self.trusted_keys).is_err() {
            return;
        }

        let Ok(loaded) = loader::load_library(path) else {
            return; // Skip invalid dylibs during discovery
        };
        for plugin in &loaded.plugins {
            if loader::validate_against_interface(
                plugin,
                self.expected_hash,
                self.expected_strategy,
            )
            .is_ok()
            {
                plugins.push(plugin.info.clone());
            }
        }
    }
discover_package private
fn discover_package (& self , dir : & Path , plugins : & mut Vec < PluginInfo >)

Discover a directory-based package (package.toml) and surface it by runtime. Rust source packages are discovered via their built dylib (the loadable artifact), not here, so they're skipped.

Source
    fn discover_package(&self, dir: &Path, plugins: &mut Vec<PluginInfo>) {
        let Ok(manifest) = fidius_core::package::load_manifest_untyped(dir) else {
            return;
        };
        use fidius_core::package::PackageRuntime;
        let runtime = match manifest.package.runtime() {
            PackageRuntime::Python => PluginRuntimeKind::Python,
            PackageRuntime::Wasm => PluginRuntimeKind::Wasm,
            // The cdylib is the loadable artifact for a Rust package; the
            // source directory isn't discovered.
            PackageRuntime::Rust => return,
        };
        plugins.push(PluginInfo {
            name: manifest.package.name.clone(),
            interface_name: manifest.package.interface.clone(),
            // Hash is unknown until load (the host validates against the
            // descriptor at load time, not discovery). Surface 0 so callers
            // know discovery alone hasn't validated the package.
            interface_hash: 0,
            interface_version: manifest.package.interface_version,
            capabilities: 0,
            buffer_strategy: BufferStrategyKind::PluginAllocated,
            runtime,
        });
    }
load pub
fn load (& self , name : & str) -> Result < LoadedPlugin , LoadError >

Load a specific plugin by name.

Searches all configured paths for a dylib containing a plugin with the given name. Returns the loaded plugin ready for calling.

Source
    pub fn load(&self, name: &str) -> Result<LoadedPlugin, LoadError> {
        #[cfg(feature = "tracing")]
        tracing::info!(plugin_name = name, "loading plugin");

        for search_path in &self.search_paths {
            if !search_path.is_dir() {
                continue;
            }

            let entries = std::fs::read_dir(search_path)?;
            for entry in entries {
                let entry = entry?;
                let path = entry.path();

                if !is_dylib(&path) {
                    continue;
                }

                // Verify signature if required — always enforced regardless of LoadPolicy
                if self.require_signature {
                    signing::verify_signature(&path, &self.trusted_keys)?;
                }

                match loader::load_library(&path) {
                    Ok(loaded) => {
                        for plugin in loaded.plugins {
                            if plugin.info.name == name {
                                loader::validate_against_interface(
                                    &plugin,
                                    self.expected_hash,
                                    self.expected_strategy,
                                )?;
                                return Ok(plugin);
                            }
                        }
                    }
                    Err(_) => continue,
                }
            }
        }

        Err(LoadError::PluginNotFound {
            name: name.to_string(),
        })
    }
find_python_package pub
fn find_python_package (& self , name : & str) -> Result < PathBuf , LoadError >

Find a python plugin package directory by name across the configured search paths. The plugin name is matched against package.toml's [package].name. Returns the directory path on success.

Source
    pub fn find_python_package(&self, name: &str) -> Result<PathBuf, LoadError> {
        for search_path in &self.search_paths {
            if !search_path.is_dir() {
                continue;
            }
            let entries = std::fs::read_dir(search_path)?;
            for entry in entries {
                let entry = entry?;
                let path = entry.path();
                if !path.is_dir() {
                    continue;
                }
                if !path.join("package.toml").exists() {
                    continue;
                }
                let Ok(manifest) = fidius_core::package::load_manifest_untyped(&path) else {
                    continue;
                };
                if matches!(
                    manifest.package.runtime(),
                    fidius_core::package::PackageRuntime::Python
                ) && manifest.package.name == name
                {
                    return Ok(path);
                }
            }
        }
        Err(LoadError::PluginNotFound {
            name: name.to_string(),
        })
    }
load_python pub
fn load_python (& self , name : & str , descriptor : & 'static fidius_core :: python_descriptor :: PythonInterfaceDescriptor ,) -> Result < crate :: handle :: PluginHandle , LoadError >

Load a Python plugin package by name and validate it against the supplied interface descriptor.

The caller passes the static <TraitName>_PYTHON_DESCRIPTOR emitted by the interface crate's #[plugin_interface] macro — that's the out-of-band hint the loader needs to map method names to vtable indices and to check the interface hash. Available only when fidius-host is built with the python feature.

Source
    pub fn load_python(
        &self,
        name: &str,
        descriptor: &'static fidius_core::python_descriptor::PythonInterfaceDescriptor,
    ) -> Result<crate::handle::PluginHandle, LoadError> {
        let dir = self.find_python_package(name)?;
        // Signature policy — enforced identically to cdylib/WASM loads.
        if self.require_signature {
            signing::verify_package_signature(&dir, &self.trusted_keys)?;
        }
        let manifest = fidius_core::package::load_manifest_untyped(&dir)
            .map_err(|e| LoadError::PythonLoad(e.to_string()))?;
        let py = fidius_python::load_python_plugin(&dir, descriptor)
            .map_err(|e| LoadError::PythonLoad(e.to_string()))?;
        // Build the host-facing metadata from the manifest header + the
        // interface descriptor. `capabilities`/`buffer_strategy` are cdylib
        // concepts and take their no-op defaults for Python.
        let info = crate::types::PluginInfo {
            name: manifest.package.name.clone(),
            interface_name: descriptor.interface_name.to_string(),
            interface_hash: descriptor.interface_hash,
            interface_version: manifest.package.interface_version,
            capabilities: 0,
            buffer_strategy: fidius_core::descriptor::BufferStrategyKind::PluginAllocated,
            runtime: crate::types::PluginRuntimeKind::Python,
        };
        Ok(crate::handle::PluginHandle::from_python(py, info))
    }
load_python_configured pub
fn load_python_configured < C : serde :: Serialize > (& self , name : & str , descriptor : & 'static fidius_core :: python_descriptor :: PythonInterfaceDescriptor , config : & C ,) -> Result < crate :: handle :: PluginHandle , LoadError >

Load a configured Python plugin (FIDIUS-A-0006 / CI.4): serialize config and bind it once via the module's __fidius_configure__(config) -> instance; methods then run on the configured instance. N differently-configured instances coexist. Available only with the python feature.

Source
    pub fn load_python_configured<C: serde::Serialize>(
        &self,
        name: &str,
        descriptor: &'static fidius_core::python_descriptor::PythonInterfaceDescriptor,
        config: &C,
    ) -> Result<crate::handle::PluginHandle, LoadError> {
        let dir = self.find_python_package(name)?;
        if self.require_signature {
            signing::verify_package_signature(&dir, &self.trusted_keys)?;
        }
        let manifest = fidius_core::package::load_manifest_untyped(&dir)
            .map_err(|e| LoadError::PythonLoad(e.to_string()))?;
        let cfg = serde_json::to_value(config)
            .map_err(|e| LoadError::PythonLoad(format!("config serialize: {e}")))?;
        let py = fidius_python::load_python_plugin_configured(&dir, descriptor, &cfg)
            .map_err(|e| LoadError::PythonLoad(e.to_string()))?;
        let info = crate::types::PluginInfo {
            name: manifest.package.name.clone(),
            interface_name: descriptor.interface_name.to_string(),
            interface_hash: descriptor.interface_hash,
            interface_version: manifest.package.interface_version,
            capabilities: 0,
            buffer_strategy: fidius_core::descriptor::BufferStrategyKind::PluginAllocated,
            runtime: crate::types::PluginRuntimeKind::Python,
        };
        Ok(crate::handle::PluginHandle::from_python(py, info))
    }
find_wasm_package pub
fn find_wasm_package (& self , name : & str) -> Result < PathBuf , LoadError >

Find a WASM package directory by name across the search paths (matches package.toml [package].name with runtime = "wasm").

Source
    pub fn find_wasm_package(&self, name: &str) -> Result<PathBuf, LoadError> {
        for search_path in &self.search_paths {
            if !search_path.is_dir() {
                continue;
            }
            for entry in std::fs::read_dir(search_path)? {
                let entry = entry?;
                let path = entry.path();
                if !path.is_dir() || !path.join("package.toml").exists() {
                    continue;
                }
                let Ok(manifest) = fidius_core::package::load_manifest_untyped(&path) else {
                    continue;
                };
                if matches!(
                    manifest.package.runtime(),
                    fidius_core::package::PackageRuntime::Wasm
                ) && manifest.package.name == name
                {
                    return Ok(path);
                }
            }
        }
        Err(LoadError::PluginNotFound {
            name: name.to_string(),
        })
    }
load_wasm pub
fn load_wasm (& self , name : & str , descriptor : & 'static fidius_core :: wasm_descriptor :: WasmInterfaceDescriptor ,) -> Result < crate :: handle :: PluginHandle , LoadError >

Load a WASM component plugin package by name and validate it against the supplied interface descriptor (the <TraitName>_WASM_DESCRIPTOR the interface crate emits). Returns a unified [crate::handle::PluginHandle].

The component is sandboxed: WASI is wired into the Linker but the guest gets a zero-grant WasiCtx (no FS preopens, no env, no sockets). The capability allow-list in [wasm].capabilities is applied in T-0104. Outbound HTTP is governed by the host's egress policy: a guest that declares the http capability gets wasi:http only when the host was given a policy (via [PluginHostBuilder::egress] or [Self::load_wasm_with_egress]) — otherwise it fails closed. Available only with the wasm feature.

Source
    pub fn load_wasm(
        &self,
        name: &str,
        descriptor: &'static fidius_core::wasm_descriptor::WasmInterfaceDescriptor,
    ) -> Result<crate::handle::PluginHandle, LoadError> {
        self.load_wasm_impl(name, descriptor, self.egress.clone(), None, None)
    }
load_wasm_configured pub
fn load_wasm_configured < C : serde :: Serialize > (& self , name : & str , descriptor : & 'static fidius_core :: wasm_descriptor :: WasmInterfaceDescriptor , config : & C ,) -> Result < crate :: handle :: PluginHandle , LoadError >

Load a configured WASM plugin (FIDIUS-A-0006 / CI.3): serialize config and bind it once via the guest's fidius-configure export. The component then runs on a persistent store, so methods dispatch on the configured instance and config crosses the sandbox boundary exactly once. Available only with the wasm feature.

Source
    pub fn load_wasm_configured<C: serde::Serialize>(
        &self,
        name: &str,
        descriptor: &'static fidius_core::wasm_descriptor::WasmInterfaceDescriptor,
        config: &C,
    ) -> Result<crate::handle::PluginHandle, LoadError> {
        let cfg = fidius_core::wire::serialize(config)
            .map_err(|e| LoadError::WasmLoad(format!("config serialize: {e}")))?;
        self.load_wasm_impl(name, descriptor, self.egress.clone(), Some(&cfg), None)
    }
load_wasm_configured_with_grants pub
fn load_wasm_configured_with_grants < C : serde :: Serialize > (& self , name : & str , descriptor : & 'static fidius_core :: wasm_descriptor :: WasmInterfaceDescriptor , config : & C , capabilities : Vec < String > , egress : Option < Arc < dyn crate :: executor :: wasm :: EgressPolicy > > ,) -> Result < crate :: handle :: PluginHandle , LoadError >

Load a configured WASM plugin with a caller-supplied capability allow-list and egress policy, overriding the package manifest's [wasm].capabilities (FIDIUS-I-0033 / cloacina constructor grants).

This is the entry point for embedders that authorize a plugin's host access at load time rather than trusting the (signed-but-author-chosen) manifest caps — e.g. cloacina's tenant-granted constructor capabilities, where the filesystem path / env key / http+tcp intent are decided by the deploying tenant, not the plugin author. capabilities fully replaces the manifest list (it is not merged): pass exactly what the tenant granted. Default-closed falls out naturally — an empty capabilities builds a zero-grant WasiCtx, and egress: None denies all brokered HTTP/TCP (the two-key gate's host key is absent). capabilities uses the same vocabulary as [wasm].capabilities (http, tcp, udp, network/sockets, fs:ro:<path>/fs:rw:<path>, env:<NAME>, …) and is validated identically; an unknown or coarse (env / fs) entry fails the load. Available only with the wasm feature.

Source
    pub fn load_wasm_configured_with_grants<C: serde::Serialize>(
        &self,
        name: &str,
        descriptor: &'static fidius_core::wasm_descriptor::WasmInterfaceDescriptor,
        config: &C,
        capabilities: Vec<String>,
        egress: Option<Arc<dyn crate::executor::wasm::EgressPolicy>>,
    ) -> Result<crate::handle::PluginHandle, LoadError> {
        let cfg = fidius_core::wire::serialize(config)
            .map_err(|e| LoadError::WasmLoad(format!("config serialize: {e}")))?;
        self.load_wasm_impl(name, descriptor, egress, Some(&cfg), Some(capabilities))
    }
load_wasm_with_egress pub
fn load_wasm_with_egress (& self , name : & str , descriptor : & 'static fidius_core :: wasm_descriptor :: WasmInterfaceDescriptor , egress : impl crate :: executor :: wasm :: EgressPolicy ,) -> Result < crate :: handle :: PluginHandle , LoadError >

Like [Self::load_wasm] but with a per-plugin wasi:http egress policy that overrides any host-wide default (FIDIUS-I-0027). This is the right primitive for isolating connectors: a host-wide policy only sees the outbound request, not which plugin issued it, so per-plugin policies are how you bound connector A to one set of hosts and connector B to another.

Source
    pub fn load_wasm_with_egress(
        &self,
        name: &str,
        descriptor: &'static fidius_core::wasm_descriptor::WasmInterfaceDescriptor,
        egress: impl crate::executor::wasm::EgressPolicy,
    ) -> Result<crate::handle::PluginHandle, LoadError> {
        self.load_wasm_impl(name, descriptor, Some(Arc::new(egress)), None, None)
    }
load_wasm_impl private
fn load_wasm_impl (& self , name : & str , descriptor : & 'static fidius_core :: wasm_descriptor :: WasmInterfaceDescriptor , egress : Option < Arc < dyn crate :: executor :: wasm :: EgressPolicy > > , config : Option < & [u8] > , caps_override : Option < Vec < String > > ,) -> Result < crate :: handle :: PluginHandle , LoadError >
Source
    fn load_wasm_impl(
        &self,
        name: &str,
        descriptor: &'static fidius_core::wasm_descriptor::WasmInterfaceDescriptor,
        egress: Option<Arc<dyn crate::executor::wasm::EgressPolicy>>,
        config: Option<&[u8]>,
        caps_override: Option<Vec<String>>,
    ) -> Result<crate::handle::PluginHandle, LoadError> {
        use crate::executor::wasm::{WasmComponentExecutor, WasmMethod};

        let dir = self.find_wasm_package(name)?;
        // Signature policy — enforced identically to cdylib/Python loads.
        if self.require_signature {
            signing::verify_package_signature(&dir, &self.trusted_keys)?;
        }
        let manifest = fidius_core::package::load_manifest_untyped(&dir)
            .map_err(|e| LoadError::WasmLoad(e.to_string()))?;
        let wasm_meta = manifest
            .wasm
            .as_ref()
            .ok_or_else(|| LoadError::WasmLoad("manifest is missing the [wasm] section".into()))?;

        let methods: Vec<WasmMethod> = descriptor
            .methods
            .iter()
            .map(|m| WasmMethod {
                name: m.name.to_string(),
                wire_raw: m.wire_raw,
                streaming: m.streaming,
            })
            .collect();
        let info = crate::types::PluginInfo {
            name: manifest.package.name.clone(),
            interface_name: descriptor.interface_name.to_string(),
            interface_hash: descriptor.interface_hash,
            interface_version: manifest.package.interface_version,
            capabilities: 0,
            buffer_strategy: fidius_core::descriptor::BufferStrategyKind::PluginAllocated,
            runtime: crate::types::PluginRuntimeKind::Wasm,
        };
        let interface = descriptor.interface_export.to_string();
        // A caller-supplied allow-list (e.g. tenant-granted constructor caps)
        // fully replaces the manifest's author-chosen `[wasm].capabilities`;
        // absent an override we honor the manifest as before.
        let capabilities = caps_override.unwrap_or_else(|| wasm_meta.capabilities.clone());

        // Resolve a precompiled .cwasm: explicit `[wasm].precompiled`, or an
        // auto-detected sibling `<component-stem>.cwasm`. The AOT path is purely
        // a load-latency optimization, so a stale/mismatched .cwasm (built by a
        // different wasmtime) is non-fatal — we log and JIT-compile the
        // component instead (FIDIUS-T-0107).
        let cwasm_path = wasm_meta
            .precompiled
            .as_ref()
            .map(|p| dir.join(p))
            .or_else(|| {
                let sibling = dir.join(&wasm_meta.component).with_extension("cwasm");
                sibling.exists().then_some(sibling)
            });

        let jit = |interface: String, methods, capabilities, info| -> Result<_, LoadError> {
            let bytes = std::fs::read(dir.join(&wasm_meta.component))?;
            WasmComponentExecutor::from_component_bytes_with_egress(
                &bytes,
                interface,
                methods,
                capabilities,
                egress.clone(),
                info,
            )
            .map_err(|e| LoadError::WasmLoad(e.to_string()))
        };

        let executor = match cwasm_path {
            Some(cwasm) if cwasm.exists() => {
                let bytes = std::fs::read(&cwasm)?;
                // SAFETY: .cwasm is produced by `fidius pack`
                // (Engine::precompile_component); wasmtime validates the header
                // and refuses a mismatched engine/version (→ Err → JIT fallback).
                let aot = unsafe {
                    WasmComponentExecutor::from_cwasm_with_egress(
                        &bytes,
                        interface.clone(),
                        methods.clone(),
                        capabilities.clone(),
                        egress.clone(),
                        info.clone(),
                    )
                };
                match aot {
                    Ok(e) => e,
                    Err(_err) => {
                        #[cfg(feature = "tracing")]
                        tracing::warn!(
                            cwasm = %cwasm.display(),
                            error = %_err,
                            "precompiled .cwasm rejected (likely engine/version mismatch); falling back to JIT"
                        );
                        jit(interface, methods, capabilities, info)?
                    }
                }
            }
            _ => jit(interface, methods, capabilities, info)?,
        };

        // Interface-hash integrity check (parity with cdylib/Python).
        let got = executor
            .interface_hash()
            .map_err(|e| LoadError::WasmLoad(e.to_string()))?;
        if got != descriptor.interface_hash {
            return Err(LoadError::InterfaceHashMismatch {
                got,
                expected: descriptor.interface_hash,
            });
        }

        // FIDIUS-A-0006 / CI.3: bind config once via the guest `fidius-configure`
        // export, retaining a persistent store for subsequent method calls.
        let mut executor = executor;
        if let Some(cfg) = config {
            executor
                .configure(cfg)
                .map_err(|e| LoadError::WasmLoad(e.to_string()))?;
        }
        Ok(crate::handle::PluginHandle::from_wasm(executor))
    }

fidius-host::host::PluginHostBuilder

pub

Builder for configuring a PluginHost.

Fields

Name Type Description
search_paths Vec < PathBuf >
load_policy LoadPolicy
require_signature bool
trusted_keys Vec < VerifyingKey >
expected_hash Option < u64 >
expected_strategy Option < BufferStrategyKind >
egress Option < Arc < dyn crate :: executor :: wasm :: EgressPolicy > >

Methods

new private
fn new () -> Self
Source
    fn new() -> Self {
        Self {
            search_paths: Vec::new(),
            load_policy: LoadPolicy::Strict,
            require_signature: false,
            trusted_keys: Vec::new(),
            expected_hash: None,
            expected_strategy: None,
            #[cfg(feature = "wasm")]
            egress: None,
        }
    }
egress pub
fn egress (mut self , policy : impl crate :: executor :: wasm :: EgressPolicy) -> Self

Set a host-wide default wasi:http egress policy (FIDIUS-I-0027). Every load_wasm then enables outbound HTTP for a guest that declares the http capability, routing each request through policy. Without this (and without a per-load policy), wasi:http is never linked and a guest that imports it fails closed. Available only with the wasm feature.

Source
    pub fn egress(mut self, policy: impl crate::executor::wasm::EgressPolicy) -> Self {
        self.egress = Some(Arc::new(policy));
        self
    }
egress_policy pub
fn egress_policy (mut self , policy : Arc < dyn crate :: executor :: wasm :: EgressPolicy >) -> Self

Like [Self::egress] but accepts an already-erased Arc<dyn EgressPolicy> — for a policy that is shared across hosts, or selected/constructed at runtime (where the concrete type isn't known at the call site). Threads through load_wasm exactly like egress. Available only with the wasm feature.

Source
    pub fn egress_policy(mut self, policy: Arc<dyn crate::executor::wasm::EgressPolicy>) -> Self {
        self.egress = Some(policy);
        self
    }
search_path pub
fn search_path (mut self , path : impl Into < PathBuf >) -> Self

Add a directory to search for plugin dylibs.

Source
    pub fn search_path(mut self, path: impl Into<PathBuf>) -> Self {
        self.search_paths.push(path.into());
        self
    }
load_policy pub
fn load_policy (mut self , policy : LoadPolicy) -> Self

Set the load policy (Strict or Lenient).

Source
    pub fn load_policy(mut self, policy: LoadPolicy) -> Self {
        self.load_policy = policy;
        self
    }
require_signature pub
fn require_signature (mut self , require : bool) -> Self

Require plugins to have valid signatures.

Source
    pub fn require_signature(mut self, require: bool) -> Self {
        self.require_signature = require;
        self
    }
trusted_keys pub
fn trusted_keys (mut self , keys : & [VerifyingKey]) -> Self

Set trusted Ed25519 public keys for signature verification.

Source
    pub fn trusted_keys(mut self, keys: &[VerifyingKey]) -> Self {
        self.trusted_keys = keys.to_vec();
        self
    }
interface_hash pub
fn interface_hash (mut self , hash : u64) -> Self

Set the expected interface hash for validation.

Source
    pub fn interface_hash(mut self, hash: u64) -> Self {
        self.expected_hash = Some(hash);
        self
    }
buffer_strategy pub
fn buffer_strategy (mut self , strategy : BufferStrategyKind) -> Self

Set the expected buffer strategy for validation.

Source
    pub fn buffer_strategy(mut self, strategy: BufferStrategyKind) -> Self {
        self.expected_strategy = Some(strategy);
        self
    }
build pub
fn build (self) -> Result < PluginHost , LoadError >

Build the PluginHost.

Source
    pub fn build(self) -> Result<PluginHost, LoadError> {
        Ok(PluginHost {
            search_paths: self.search_paths,
            load_policy: self.load_policy,
            require_signature: self.require_signature,
            trusted_keys: self.trusted_keys,
            expected_hash: self.expected_hash,
            expected_strategy: self.expected_strategy,
            #[cfg(feature = "wasm")]
            egress: self.egress,
        })
    }

Functions

fidius-host::host::is_dylib

private

fn is_dylib (path : & Path) -> bool

Check if a path has a platform-appropriate dylib extension.

Source
fn is_dylib(path: &Path) -> bool {
    let ext = path.extension().and_then(|e| e.to_str()).unwrap_or("");
    if cfg!(target_os = "macos") {
        ext == "dylib"
    } else if cfg!(target_os = "windows") {
        ext == "dll"
    } else {
        ext == "so"
    }
}