sqlite_functions/lib.rs
1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(feature = "loadable-extension"), forbid(unsafe_code))]
3
4//! The crate's public API is intentionally small: describe a function with
5//! [`FunctionOptions`], register it, and reuse the same registration function
6//! from Rust or a loadable extension.
7
8mod options;
9mod register;
10
11#[cfg(feature = "loadable-extension")]
12#[doc(hidden)]
13pub mod __private;
14
15pub use options::{Arity, FunctionOptions};
16pub use register::{register_aggregate, register_scalar};
17
18/// Re-exported so extension crates use the exact `rusqlite` version expected by
19/// this crate.
20pub use rusqlite;
21
22/// Generate SQLite's conventional loadable-extension entry point.
23///
24/// The supplied function must have the signature
25/// `fn(&sqlite_functions::rusqlite::Connection) -> sqlite_functions::rusqlite::Result<()>`.
26///
27/// This macro is available only when the `loadable-extension` feature is
28/// enabled. Invoke it once in a `cdylib` crate.
29#[cfg(feature = "loadable-extension")]
30#[macro_export]
31macro_rules! export_extension {
32 ($register:path) => {
33 #[doc = "SQLite loadable-extension entry point."]
34 ///
35 /// # Safety
36 ///
37 /// This function must only be called by SQLite with pointers supplied
38 /// to an extension entry point.
39 #[unsafe(no_mangle)]
40 pub unsafe extern "C" fn sqlite3_extension_init(
41 db: *mut $crate::rusqlite::ffi::sqlite3,
42 error_message: *mut *mut ::std::os::raw::c_char,
43 api: *mut $crate::rusqlite::ffi::sqlite3_api_routines,
44 ) -> ::std::os::raw::c_int {
45 fn register(
46 connection: $crate::rusqlite::Connection,
47 ) -> $crate::rusqlite::Result<bool> {
48 $register(&connection)?;
49 Ok(false)
50 }
51
52 // SAFETY: SQLite owns these pointers and invokes this exported
53 // entry point according to its loadable-extension ABI.
54 unsafe { $crate::__private::initialize(db, error_message, api, register) }
55 }
56 };
57}