1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// Copyright 2026 Colliery, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Fidius — a Rust plugin framework for trait-to-dylib plugin systems.
//!
//! This is the facade crate. Interface crates should depend on `fidius` only.
//! It re-exports everything needed to define interfaces and implement plugins.
//!
//! # For interface crate authors
//!
//! ```ignore
//! pub use fidius::{plugin_impl, PluginError};
//!
//! #[fidius::plugin_interface(version = 1, buffer = PluginAllocated)]
//! pub trait MyPlugin: Send + Sync {
//! fn process(&self, input: String) -> String;
//! }
//! ```
//!
//! # For plugin crate authors
//!
//! ```ignore
//! use my_interface::{plugin_impl, MyPlugin, PluginError};
//!
//! pub struct MyImpl;
//!
//! #[plugin_impl(MyPlugin)]
//! impl MyPlugin for MyImpl {
//! fn process(&self, input: String) -> String {
//! format!("processed: {input}")
//! }
//! }
//!
//! fidius::fidius_plugin_registry!();
//! ```
//!
//! # What fidius does *not* provide: timeouts and cancellation
//!
//! Fidius has **no built-in timeout, deadline, or cancellation mechanism**
//! for plugin method calls. A call to `PluginHandle::call_method` (or
//! `call_method_raw`) runs to completion, panics, or — in the case of a
//! truly stuck plugin — never returns. There is no `PluginError::Timeout`
//! variant and the framework will not interrupt a misbehaving plugin.
//!
//! This is a deliberate consequence of the cdylib + in-process architecture:
//! plugin code runs synchronously on the host's calling thread, and Rust
//! cannot safely interrupt a thread mid-FFI-call. Any honest timeout
//! implementation requires running the plugin in a separate, killable
//! process — out of scope for the current framework.
//!
//! **If your threat model includes runaway plugins, you must add a
//! watchdog yourself.** The usual pattern is to run the host process
//! itself with a supervisor that can SIGKILL it on deadline; per-call
//! timeouts inside a single host process are not safely achievable for
//! arbitrary plugin code.
//!
//! Future work: the `fidius-python` initiative is the natural carrier for
//! a real subprocess-isolated execution tier, which would be the only path
//! by which fidius could grow first-class timeout semantics.
// Re-export macros.
//
// # Wire mode
//
// By default every method argument and return value is bincode-encoded
// across the FFI boundary. For methods whose argument and return are
// already byte buffers (image data, ML tensors, pre-encoded Arrow IPC,
// protobuf payloads, etc.) bincode is wasted overhead — it just adds
// length-prefixing and an extra alloc+memcpy on each side.
//
// Annotate such methods with `#[wire(raw)]` on both the trait declaration
// (in the interface crate) and the impl method (in the plugin crate). The
// signature must be exactly:
//
// ```ignore
// #[wire(raw)]
// fn process(&self, data: Vec<u8>) -> Vec<u8>;
// // or
// #[wire(raw)]
// fn process(&self, data: Vec<u8>) -> Result<Vec<u8>, MyError>;
// ```
//
// Errors and panic messages still go through bincode (small typed payloads).
// Host/plugin disagreement on wire mode for a given method surfaces as an
// interface-hash mismatch at load time — never as silent data corruption.
//
// Mix freely: one trait can have raw methods alongside normal typed methods.
pub use ;
// Re-export modules so generated code can use fidius::descriptor::, fidius::status::, etc.
pub use descriptor;
pub use error;
pub use hash;
pub use python_descriptor;
pub use status;
pub use stream_ffi;
pub use stream_marker;
pub use wasm_descriptor;
pub use wire;
/// Brokered outbound HTTP (`get`/`post`/`send`) for sandboxed WASM connectors
/// (FIDIUS-I-0028). Present only in `wasm32-wasip2` builds; a connector's
/// `read()` calls it and the host's `EgressPolicy` brokers the request.
pub use http;
// Also re-export key types at the crate root for convenience
pub use ;
pub use PluginError;
pub use ;
/// The `fidius::Stream<T>` server-streaming return marker — write it as a
/// method's return type in a `#[plugin_interface]` trait to declare a
/// server-streaming method. See [`fidius_core::stream_marker::Stream`].
pub use Stream;
/// The neutral value model + (de)serialization helpers host consumers use to
/// decode `ChunkStream` items and dynamic `Value`s.
pub use ;
pub use async_runtime;
// Host-side API surface — only present when the `host` feature is enabled.
// Plugin crates (cdylibs) do not enable this feature and therefore do not
// pull libloading or other host-only dependencies.
pub use ;
// Server-streaming host handle (FIDIUS-I-0026). The generated Client's streaming
// methods return this; consumers pull items with `.next().await`.
pub use ;
// WASM egress contract (FIDIUS-I-0027): name these to implement a per-request egress
// policy for `PluginHost::builder().egress(..)`. Requires the `wasm` feature.
pub use ;
// Re-export inventory so fidius_plugin_registry!() works via fidius_core
pub use inventory;
// Re-export the registry module for fidius_plugin_registry!() macro
pub use registry;
// Re-export the fidius_plugin_registry!() macro.
// Because it uses $crate:: paths, it resolves to fidius_core:: when called
// as fidius_core::fidius_plugin_registry!(), which works because fidius
// re-exports the necessary modules. Plugin authors call it as:
// fidius::fidius_plugin_registry!();
pub use fidius_plugin_registry;