Skip to main content

unofficial_extras/
util.rs

1use std::{
2    ffi::{CStr, c_char},
3    slice,
4};
5
6/// Helper to convert a string pointer to a [`prim@str`].
7#[inline]
8pub unsafe fn str_from_cstr<'a>(ptr: *const c_char) -> Option<&'a str> {
9    if ptr.is_null() {
10        None
11    } else {
12        unsafe { CStr::from_ptr(ptr) }.to_str().ok()
13    }
14}
15
16/// Helper to convert a string pointer and a length to a [`prim@str`].
17///
18/// The pointer needs to be non-null. Panics if the string is invalid UTF-8.
19#[inline]
20#[allow(dead_code)]
21pub unsafe fn str_from_cstr_len<'a>(ptr: *const c_char, len: u64) -> &'a str {
22    let slice = unsafe { slice::from_raw_parts(ptr as *const u8, len as usize) };
23    str::from_utf8(slice).expect("cstr with invalid utf8")
24}
25
26/// Strips the `':'` prefix from an account name if present.
27#[inline]
28pub fn strip_account_prefix(account_name: &str) -> &str {
29    account_name.strip_prefix(':').unwrap_or(account_name)
30}
31
32/// Helper to define function types with optional unwind ABI.
33macro_rules! abi {
34    ( $( $vis:vis type $name:ident = unsafe extern fn( $( $args:tt )* ) $( -> $ret:ty )? ; )* ) => {
35        $(
36            #[cfg(feature = "unwind")]
37            $vis type $name = unsafe extern "C-unwind" fn( $( $args )* ) $( -> $ret )?;
38
39            #[cfg(not(feature = "unwind"))]
40            $vis type $name = unsafe extern "C" fn( $( $args )* ) $( -> $ret )?;
41        )*
42    };
43}
44
45pub(crate) use abi;