macro_rules! export_count_getter {
(
$(#[$meta:meta])*
$slot:path,
$name:ident($handle:ident: $handle_ty:ty $(, $arg:ident: $arg_ty:ty)* $(,)?),
$body:block
) => { ... };
}Expand description
Declare an entry point that hands out a count.
$body evaluates to Result<c_int, FfiError>. Failure — including a null handle —
returns -1, which is why this is its own macro rather than a sentinel argument to a
general one: a sentinel that can be passed in is a sentinel that can be passed wrong.
The slot is cleared on entry like everywhere else, and here that is load-bearing rather
than tidy. A count getter returns a value instead of a pointer, so a caller polling
<lib>_last_error_kind after it has no other way to know the recorded failure is not
someone else’s.
unparser_shared::export_count_getter!(
/// The number of pages, or -1 on failure.
///
/// # Safety
///
/// - `doc` must be a valid handle.
LAST_ERROR,
demo4_page_count(doc: Demo4Document),
{ Ok(unsafe { (*doc).inner.pages.len() } as std::ffi::c_int) }
);
assert_eq!(unsafe { demo4_page_count(std::ptr::null()) }, -1);
assert_eq!(demo4_last_error_kind(), unparser_shared::kind::INVALID_ARGUMENT);
let doc = Box::into_raw(Box::new(Demo4Document { inner: Book { pages: vec![1, 2] } }));
assert_eq!(unsafe { demo4_page_count(doc) }, 2);
assert_eq!(demo4_last_error_kind(), unparser_shared::kind::NONE);
unsafe { demo4_free_document(doc) };