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:
12//!
13//! ```ignore
14//! use wolfram_export::export;
15//!
16//! #[export] fn add(a: f64, b: f64) -> f64 { a + b }
17//! #[export(wstp)] fn foo(link: &mut Link) { /* ... */ }
18//! #[export(wxf)] fn dot(a: Vec<f64>, b: Vec<f64>) -> f64 { /* ... */ }
19//! ```
20//!
21//! Each mode's wire shape, runtime, and Cargo dep set live in its own
22//! feature-gated submodule below. The `ExportEntry` inventory and the
23//! `__wolfram_manifest__` C symbol are always on (they're tiny and how the
24//! `cargo wl build` tool discovers exports).
25
26#![allow(missing_docs)]
27
28//==============================================================================
29// Always-on: shared inventory + manifest plumbing. The actual definitions live
30// in the `wolfram-export-core` workspace-internal crate (so `wolfram-library-link`
31// can depend on them without creating a cycle through `wolfram-export`).
32//==============================================================================
33
34pub use ::wolfram_export_core::ExportEntry;
35
36#[cfg(feature = "automate-function-loading-boilerplate")]
37pub use ::wolfram_export_core::exported_library_functions_association;
38
39#[cfg(feature = "automate-function-loading-boilerplate")]
40#[doc(hidden)]
41pub use ::wolfram_export_core::inventory;
42
43//==============================================================================
44// Mode-gated submodules.
45//==============================================================================
46
47#[cfg(feature = "native")]
48pub mod native;
49
50#[cfg(feature = "wstp")]
51pub mod wstp;
52
53#[cfg(feature = "wxf")]
54pub mod wxf;
55
56//==============================================================================
57// Proc-macro re-exports — `wolfram_export::export` works in user code without
58// a separate `wolfram-export-macros` dep.
59//==============================================================================
60
61pub use wolfram_export_macros::{export, export_native, export_wstp, export_wxf, init};
62
63//==============================================================================
64// Macro-emission surface.
65//
66// The proc-macro emits code that names `wolfram_export::sys::*` and
67// `wolfram_export::macro_utils::*`. These resolve via the mode submodules
68// below, gated on the matching feature.
69//==============================================================================
70
71#[cfg(any(feature = "native", feature = "wxf"))]
72pub mod sys {
73 //! Raw `wolfram-library-link-sys` C-FFI types (`WolframLibraryData`,
74 //! `MArgument`, `mint`, …). Available whenever any LibraryLink-using
75 //! mode is enabled.
76 pub use ::wolfram_library_link_sys::*;
77}
78
79#[cfg(feature = "native")]
80pub use ::wolfram_library_link::NativeFunction;
81
82/// Macro-runtime helpers. Re-exports of the per-mode `macro_utils` modules
83/// behind a single `wolfram_export::macro_utils::*` namespace so the
84/// proc-macro can emit one consistent path regardless of mode.
85pub mod macro_utils {
86 #[cfg(feature = "native")]
87 pub use crate::native::macro_utils::*;
88
89 #[cfg(feature = "wstp")]
90 pub use crate::wstp::macro_utils::*;
91
92 #[cfg(feature = "wxf")]
93 pub use ::wolfram_serialize::FromWXF;
94
95 #[cfg(feature = "wxf")]
96 pub use crate::wxf::macro_utils::*;
97
98 // The `#[export(wxf)]` bridge names `NumericArray<u8>` (the input ByteArray
99 // buffer). It's `wolfram-library-link`'s runtime type — re-exported here for
100 // macro codegen only (hidden), not as part of `wolfram-export`'s public API.
101 // Users name value types via `wolfram_library_link` directly.
102 #[cfg(feature = "wxf")]
103 #[doc(hidden)]
104 pub use ::wolfram_library_link::NumericArray;
105
106 /// `LibraryLinkFunction` is a type alias for [`ExportEntry`][crate::ExportEntry].
107 /// Lives at this path because the proc-macro emits
108 /// `macro_utils::LibraryLinkFunction::{Native,Wstp,Wxf}{...}` for inventory
109 /// submission.
110 pub use crate::ExportEntry as LibraryLinkFunction;
111}
112
113//==============================================================================
114// Feature-presence asserts.
115//
116// The proc-macro emits a `const _: () = wolfram_export::__assert_<mode>_enabled();`
117// at the top of each generated wrapper. When the matching feature is OFF, the
118// const fn body is `panic!(...)` — evaluating it in a const context becomes a
119// compile-time error with a friendly, actionable message instead of a generic
120// path-resolution failure.
121//==============================================================================
122
123#[cfg(feature = "native")]
124#[doc(hidden)]
125pub const fn __assert_native_enabled() {}
126#[cfg(not(feature = "native"))]
127#[doc(hidden)]
128pub const fn __assert_native_enabled() {
129 panic!(
130 "`#[export]` (native mode) requires enabling the `native` feature of `wolfram-export`"
131 );
132}
133
134#[cfg(feature = "wstp")]
135#[doc(hidden)]
136pub const fn __assert_wstp_enabled() {}
137#[cfg(not(feature = "wstp"))]
138#[doc(hidden)]
139pub const fn __assert_wstp_enabled() {
140 panic!("`#[export(wstp)]` requires enabling the `wstp` feature of `wolfram-export`");
141}
142
143#[cfg(feature = "wxf")]
144#[doc(hidden)]
145pub const fn __assert_wxf_enabled() {}
146#[cfg(not(feature = "wxf"))]
147#[doc(hidden)]
148pub const fn __assert_wxf_enabled() {
149 panic!("`#[export(wxf)]` requires enabling the `wxf` feature of `wolfram-export`");
150}