linesmith_core/runtime/plugins.rs
1//! Runtime plugin discovery + load. Wraps
2//! `PluginRegistry::load_with_xdg` plus the cold-start fast path.
3
4use std::path::PathBuf;
5use std::sync::Arc;
6
7use linesmith_plugin::PluginRegistry;
8
9use crate::config::Config;
10use crate::data_context::xdg::{resolve_subdir, XdgEnv, XdgScope};
11use crate::plugins::build_engine;
12use crate::segments::BUILT_IN_SEGMENT_IDS;
13
14/// `$XDG_CONFIG_HOME/linesmith/segments/` (with `$HOME` fallback)
15/// per the cascade in [`crate::data_context::xdg::resolve_subdir`].
16/// `None` when neither env var is populated.
17#[must_use]
18pub fn xdg_segments_dir(env: &XdgEnv) -> Option<PathBuf> {
19 resolve_subdir(env, XdgScope::Config, "segments")
20}
21
22/// Discover + compile plugins from `cfg.plugin_dirs` plus the XDG
23/// segments dir. Returns `None` when neither `cfg.plugin_dirs` is
24/// configured nor an XDG segments directory exists on disk —
25/// cold-start fast path that skips `build_engine` entirely.
26/// (Configured-but-missing entries in `cfg.plugin_dirs` take the
27/// `Some` path and surface as load errors on the registry.)
28/// Callers consume `registry.load_errors()` per their needs: the
29/// driver writes them to stderr; doctor classifies them across the
30/// `plugins.compile` / `plugins.deps_valid` /
31/// `plugins.no_id_collisions` / `plugins.no_builtin_collisions`
32/// check rows.
33#[must_use]
34pub fn load_plugins(
35 cfg: Option<&Config>,
36 xdg_env: &XdgEnv,
37) -> Option<(PluginRegistry, Arc<rhai::Engine>)> {
38 let config_dirs: &[PathBuf] = cfg.map_or(&[], |c| c.plugin_dirs.as_slice());
39 let xdg_dir = xdg_segments_dir(xdg_env);
40
41 // Cold-start fast path: no plugin source means no engine cost.
42 let xdg_present = xdg_dir.as_deref().is_some_and(|p| p.is_dir());
43 if config_dirs.is_empty() && !xdg_present {
44 return None;
45 }
46
47 let engine = build_engine();
48 let registry = PluginRegistry::load_with_xdg(
49 config_dirs,
50 xdg_dir.as_deref(),
51 &engine,
52 BUILT_IN_SEGMENT_IDS,
53 );
54 Some((registry, engine))
55}