Skip to main content

wolfram_export/
lib.rs

1//! Unified runtime for `#[export]`-marked Wolfram LibraryLink functions.
2//!
3//! Pick modes via Cargo features:
4//!
5//! ```toml
6//! wolfram-export = { version = "0.5", features = ["wxf"] }   # typed WXF
7//! wolfram-export = { version = "0.5", features = ["wstp"] }  # WSTP Link
8//! wolfram-export = "0.5"                                     # native (default)
9//! ```
10//!
11//! Then in your code (shown here with every mode enabled):
12//!
13//! ```
14//! # // Compiled and tested only when all three modes are enabled
15//! # // (e.g. `cargo test --all-features`); a no-op otherwise.
16//! # #[cfg(all(feature = "wstp", feature = "wxf"))]
17//! # mod scope {
18//! use wolfram_export::{export, wstp::Link};
19//!
20//! #[export]        fn add(a: f64, b: f64) -> f64 { a + b }
21//! #[export(wstp)]  fn echo(link: &mut Link) { let _ = link; }
22//! #[export(wxf)]   fn dot(a: Vec<f64>, b: Vec<f64>) -> f64 {
23//!     a.iter().zip(&b).map(|(x, y)| x * y).sum()
24//! }
25//! # }
26//! ```
27//!
28//! Each mode's wire shape, runtime, and Cargo dep set live in its own
29//! feature-gated submodule below. The `ExportEntry` inventory and the
30//! `__wolfram_manifest__` C symbol are always on (they're tiny and how the
31//! `cargo wl build` tool discovers exports).
32
33#![warn(missing_docs)]
34
35//==============================================================================
36// Always-on: shared inventory + manifest plumbing. The actual definitions live
37// in the `wolfram-export-core` workspace-internal crate (so `wolfram-library-link`
38// can depend on them without creating a cycle through `wolfram-export`).
39//==============================================================================
40
41pub use ::wolfram_export_core::ExportEntry;
42
43#[cfg(feature = "automate-function-loading-boilerplate")]
44pub use ::wolfram_export_core::exported_library_functions_association;
45
46#[cfg(feature = "automate-function-loading-boilerplate")]
47#[doc(hidden)]
48pub use ::wolfram_export_core::inventory;
49
50//==============================================================================
51// Mode-gated submodules.
52//==============================================================================
53
54/// Runtime support for native-mode exports (`#[export]`), which are called
55/// over the raw `MArgument` C ABI.
56#[cfg(feature = "native")]
57pub mod native;
58
59/// Runtime support for WSTP-mode exports (`#[export(wstp)]`), which are
60/// called over a WSTP `Link`.
61#[cfg(feature = "wstp")]
62pub mod wstp;
63
64/// Runtime support for WXF-mode exports (`#[export(wxf)]`), which exchange
65/// typed values as a WXF `ByteArray`.
66#[cfg(feature = "wxf")]
67pub mod wxf;
68
69//==============================================================================
70// Proc-macro re-exports — `wolfram_export::export` works in user code without
71// a separate `wolfram-export-macros` dep.
72//==============================================================================
73
74/// Export a function as a Wolfram LibraryLink function. See
75/// [`export`][macro@export] for the three wire-format modes (native, `wstp`,
76/// `wxf`) and the Cargo features each one needs.
77pub use wolfram_export_macros::export;
78
79/// Designate a one-time library-load initialization function. See
80/// [`init`][macro@init].
81pub use wolfram_export_macros::init;
82
83//==============================================================================
84// Macro-emission surface.
85//
86// The proc-macro emits code that names `wolfram_export::sys::*` and
87// `wolfram_export::macro_utils::*`. These resolve via the mode submodules
88// below, gated on the matching feature.
89//==============================================================================
90
91#[cfg(any(feature = "native", feature = "wxf"))]
92pub mod sys {
93    //! Raw `wolfram-library-link-sys` C-FFI types (`WolframLibraryData`,
94    //! `MArgument`, `mint`, …). Available whenever any LibraryLink-using
95    //! mode is enabled.
96    pub use ::wolfram_library_link_sys::*;
97}
98
99#[cfg(feature = "native")]
100pub use ::wolfram_library_link::NativeFunction;
101
102/// Macro-runtime helpers. Re-exports of the per-mode `macro_utils` modules
103/// behind a single `wolfram_export::macro_utils::*` namespace so the
104/// proc-macro can emit one consistent path regardless of mode.
105pub mod macro_utils {
106    #[cfg(feature = "native")]
107    pub use crate::native::macro_utils::*;
108
109    #[cfg(feature = "wstp")]
110    pub use crate::wstp::macro_utils::*;
111
112    #[cfg(feature = "wxf")]
113    pub use ::wolfram_serialize::FromWXF;
114
115    #[cfg(feature = "wxf")]
116    pub use crate::wxf::macro_utils::*;
117
118    // The `#[export(wxf)]` bridge names `NumericArray<u8>` (the input ByteArray
119    // buffer). It's `wolfram-library-link`'s runtime type — re-exported here for
120    // macro codegen only (hidden), not as part of `wolfram-export`'s public API.
121    // Users name value types via `wolfram_library_link` directly.
122    #[cfg(feature = "wxf")]
123    #[doc(hidden)]
124    pub use ::wolfram_library_link::NumericArray;
125
126    /// `LibraryLinkFunction` is a type alias for [`ExportEntry`][crate::ExportEntry].
127    /// Lives at this path because the proc-macro emits
128    /// `macro_utils::LibraryLinkFunction::{Native,Wstp,Wxf}{...}` for inventory
129    /// submission.
130    pub use crate::ExportEntry as LibraryLinkFunction;
131}
132
133//==============================================================================
134// Feature-presence asserts.
135//
136// The proc-macro emits a `const _: () = wolfram_export::__assert_<mode>_enabled();`
137// at the top of each generated wrapper. When the matching feature is OFF, the
138// const fn body is `panic!(...)` — evaluating it in a const context becomes a
139// compile-time error with a friendly, actionable message instead of a generic
140// path-resolution failure.
141//==============================================================================
142
143#[cfg(feature = "native")]
144#[doc(hidden)]
145pub const fn __assert_native_enabled() {}
146#[cfg(not(feature = "native"))]
147#[doc(hidden)]
148pub const fn __assert_native_enabled() {
149    panic!(
150        "`#[export]` (native mode) requires enabling the `native` feature of `wolfram-export`"
151    );
152}
153
154#[cfg(feature = "wstp")]
155#[doc(hidden)]
156pub const fn __assert_wstp_enabled() {}
157#[cfg(not(feature = "wstp"))]
158#[doc(hidden)]
159pub const fn __assert_wstp_enabled() {
160    panic!("`#[export(wstp)]` requires enabling the `wstp` feature of `wolfram-export`");
161}
162
163#[cfg(feature = "wxf")]
164#[doc(hidden)]
165pub const fn __assert_wxf_enabled() {}
166#[cfg(not(feature = "wxf"))]
167#[doc(hidden)]
168pub const fn __assert_wxf_enabled() {
169    panic!("`#[export(wxf)]` requires enabling the `wxf` feature of `wolfram-export`");
170}