abi_stable/proc_macro_reexports/
sabi_extern_fn.rs

1/**
2
3The `sabi_extern_fn` attribute macro allows defining `extern "C"` function that
4abort on unwind instead of causing undefined behavior.
5
6This macro is syntactic sugar to transform  this:
7```ignore
8<visibility> fn function_name( <params> ) -> <return type> {
9    <code here>
10}
11```
12into this:
13```ignore
14<visibility> extern "C" fn function_name( <params> ) -> <return type> {
15    ::abi_stable::extern_fn_panic_handling!{
16        <code here>
17    }
18}
19```
20
21What this attribute does is to give the function abort on unwind semantics
22(only when the unwinds doesn't stop inside the function).
23A user can still use [`std::panic::catch_unwind`] inside the function to 
24catch panics and handle them appropriately.
25
26### Basic examples
27
28```rust
29use abi_stable::{sabi_extern_fn, std_types::RArc, traits::IntoReprC};
30
31#[sabi_extern_fn]
32pub(crate) fn hello() -> RArc<u32> {
33    RArc::new(100)
34}
35
36assert_eq!(hello(), RArc::new(100));
37
38
39```
40
41```rust
42use abi_stable::{
43    sabi_extern_fn,
44    std_types::{RStr, RVec},
45    traits::IntoReprC,
46};
47
48#[sabi_extern_fn]
49fn collect_into_lines(text: &str) -> RVec<RStr<'_>> {
50    text.lines()
51        .filter(|x| !x.is_empty())
52        .map(RStr::from)
53        .collect()
54}
55
56assert_eq!(
57    collect_into_lines("what\nis\nthat"),
58    vec!["what".into_c(), "is".into(), "that".into()].into_c(),
59);
60
61
62
63```
64
65# no_early_return
66
67You can use `#[sabi_extern_fn(no_early_return)]` to potentially 
68improve the runtime performance of the annotated function (this has not been tested).
69
70This variant of the attribute removes an intermediate closure that is 
71used to intercept early returns (`?`, `return`, etc),
72
73If this version of the attribute is used on a function which does have an 
74early return, it will (incorrectly) abort the process when it attempts to return early.
75
76### Example
77
78```rust
79use abi_stable::{
80    sabi_extern_fn,
81    std_types::{RStr, RVec},
82    traits::IntoReprC,
83};
84
85#[sabi_extern_fn(no_early_return)]
86pub(crate) fn hello() -> RVec<RStr<'static>> {
87    vec!["hello".into(), "world".into()].into()
88}
89
90assert_eq!(hello(), vec!["hello".into_c(), "world".into()].into_c(),);
91
92
93
94```
95
96
97*/
98#[doc(inline)]
99pub use abi_stable_derive::sabi_extern_fn;