Skip to main content

export_optional_string_getter

Macro export_optional_string_getter 

Source
macro_rules! export_optional_string_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 string which may legitimately be absent.

$body evaluates to Result<Option<String>, FfiError>. Ok(None) returns null with the slot left at success, because absence is not a failure — document metadata that was never set is the case this exists for.

That makes null ambiguous on its own, and deliberately so: the kind channel is what separates the three outcomes a caller has to tell apart.

$bodyReturnsKind
Ok(Some(text))the stringsuccess
Ok(None)nullsuccess — there is nothing to give
Ok(Some(text)) holding an interior NULnullkind::INVALID_OUTPUT
Err(..)nullwhatever the body classified

Use export_string_getter! where absence cannot happen or is genuinely an empty string. Do not fold the two by defaulting absent to "" — that tells a caller the field is set and blank.

unparser_shared::export_optional_string_getter!(
    /// The document author, or null when none is recorded.
    ///
    /// # Safety
    ///
    /// - `doc` must be a valid handle.
    /// - The returned string must be freed by this library.
    LAST_ERROR,
    demo3_author(doc: Demo3Document),
    { Ok(unsafe { (*doc).inner.author.clone() }) }
);

let absent = Box::into_raw(Box::new(Demo3Document { inner: Meta { author: None } }));
assert!(unsafe { demo3_author(absent) }.is_null());
assert_eq!(demo3_last_error_kind(), unparser_shared::kind::NONE);
unsafe { demo3_free_document(absent) };