Skip to main content

linsight_plugin_sdk/
lib.rs

1// SPDX-FileCopyrightText: 2026 VisorCraft LLC
2// SPDX-License-Identifier: GPL-3.0-only
3#![deny(rust_2018_idioms)]
4#![deny(unsafe_op_in_unsafe_fn)]
5// `#[stabby::stabby]` on a trait expands to vtable-shim functions that
6// fold the trait's `&self` plus every parameter into one extern "C" call.
7// For traits with three parameters that's already 4-5 arguments, and
8// stabby adds vtable / metadata fields on top. The lint isn't actionable
9// at our level — the shape is mechanically determined by the macro.
10#![allow(clippy::too_many_arguments)]
11
12pub mod export;
13pub mod manifest;
14pub mod mirror;
15pub mod pciids;
16pub mod plugin;
17
18pub use manifest::*;
19pub use mirror::*;
20pub use plugin::*;
21
22/// Re-export of `linsight-core` so plugin authors can pin against the SDK
23/// version alone. The types every plugin needs (`SensorId`, `Reading`,
24/// `Unit`, `SensorKind`, `Category`, etc.) live there.
25pub use linsight_core;
26
27/// Re-export of `stabby` so plugin authors can pull in stabby types
28/// without adding a duplicate dependency.
29pub use stabby;
30
31/// Bump only on breaking changes to the plugin ABI. The daemon refuses
32/// to load plugins whose returned abi version does not match this
33/// constant.
34///
35/// * v1: pre-stabby raw-fat-pointer factory; `Box::from_raw` on the host.
36/// * v2: `#[stabby::stabby]` trait, R-mirror types on the FFI boundary,
37///   factory returns `stabby::dynptr!(Box<dyn LinsightPlugin + Send + Sync>)`
38///   and is loaded via `StabbyLibrary::get_stabbied`. Used
39///   `#[repr(stabby)]` tagged enums for RUnit / RReading / RCell.
40/// * v3: same factory shape as v2, but every former tagged enum
41///   (RUnit, RReading, RCell) replaced with an explicit
42///   `(kind: <Repr>Kind, payload_fields)` struct. The change works
43///   around a stabby 36.2.2 bug where `match_owned` on tagged enums
44///   with mixed unit + payload variants misroutes closures at
45///   `opt-level >= 1`. v2 plugins fail the version check at load.
46/// * v4: PluginManifest gains `devices: Vec<HardwareDevice>` and
47///   SensorDescriptor gains `device_key: Option<HardwareDeviceKey>`
48///   so each plugin reports its hardware identities for the
49///   daemon's Hardware page + nickname store. v3 plugins fail the
50///   symbol lookup at load (`linsight_plugin_v3` → `_v4`).
51/// * v5: `RPluginCtx` gains `config_json: SString` — a JSON-encoded
52///   per-plugin config blob read from `plugins.toml` by the daemon.
53///   Plugins opt in by deserializing it. v4 plugins fail the symbol
54///   lookup at load (`linsight_plugin_v4` → `_v5`).
55/// * v6: the trait methods change from `extern "C"` to `extern "C-unwind"`
56///   so a panic inside a plugin's `init`/`sample` unwinds across the FFI
57///   boundary and is caught by the daemon (`host_init`/`host_sample`)
58///   instead of force-aborting at the boundary. The vtable signature
59///   differs, so v5 plugins fail the symbol lookup at load
60///   (`linsight_plugin_v5` → `_v6`).
61pub const LINSIGHT_PLUGIN_ABI_VERSION: u32 = 6;
62
63/// Re-export of [`linsight_core::STATIC_TAG`] — the canonical sensor tag
64/// marking a value as constant for the process lifetime. Defined in
65/// linsight-core so the daemon, plugins, SDK, and GUI all share one source
66/// of truth.
67pub use linsight_core::STATIC_TAG;