Trait ffizz_passby::PassByValue
source · [−]pub trait PassByValue: Sized {
type CType: Sized;
unsafe fn from_ctype(cval: Self::CType) -> Self;
fn as_ctype(self) -> Self::CType;
unsafe fn val_from_arg(arg: Self::CType) -> Self { ... }
unsafe fn return_val(self) -> Self::CType { ... }
unsafe fn val_to_arg_out(self, arg_out: *mut Self::CType) { ... }
}Expand description
This trait supports passing data to Rust by value.
Pass-by-values implies that values are copyable, via assignment in C, so this trait is typically used to represent Copy values, and in particular values that do not contain pointers.
The Rust and C types may differ, with PassByValue::from_ctype and PassByValue::as_ctype
converting between them. These typically provide some simple conversion between a C-style
data structure and a more ergonomic Rust type.
Required Associated Types
Required Methods
unsafe fn from_ctype(cval: Self::CType) -> Self
unsafe fn from_ctype(cval: Self::CType) -> Self
Convert a C value to a Rust value.
Safety
The implementation of this method assumes that cval is a valid instance of Self::CType.
Provided Methods
unsafe fn val_from_arg(arg: Self::CType) -> Self
unsafe fn val_from_arg(arg: Self::CType) -> Self
Copy a value from C as an argument.
Safety
selfmust be a valid instance of the C type. This is typically ensured either by requiring that C code not modify it, or by defining the valid values in C comments.
Examples found in repository?
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
pub unsafe extern "C" fn uuid_version(uuid: uuid_t) -> usize {
// SAFETY:
// - tcuuid is a valid uuid_t (all byte patterns are valid)
let uuid: Uuid = unsafe { Uuid::val_from_arg(uuid) };
uuid.0.get_version_num()
}
/// Write the string representation of a uuid_t into the given buffer, which must be
/// at least UUID_STRING_BYTES long. No NUL terminator is added.
///
/// # Safety
///
/// * buf must point to at least UUID_STRING_BYTES of valid memory.
#[no_mangle]
pub unsafe extern "C" fn uuid_to_buf(tcuuid: uuid_t, buf: *mut c_char) {
debug_assert!(!buf.is_null());
// SAFETY:
// - buf is valid for len bytes (by C convention)
// - (no alignment requirements for a byte slice)
// - content of buf will not be mutated during the lifetime of this slice (lifetime
// does not outlive this function call)
// - the length of the buffer is less than isize::MAX (see docstring)
let buf: &mut [u8] =
unsafe { std::slice::from_raw_parts_mut(buf as *mut u8, UUID_STRING_BYTES) };
// SAFETY:
// - tcuuid is a valid uuid_t (all byte patterns are valid)
let uuid: Uuid = unsafe { Uuid::val_from_arg(tcuuid) };
uuid.0.as_hyphenated().encode_lower(buf);
}unsafe fn return_val(self) -> Self::CType
unsafe fn return_val(self) -> Self::CType
Return a value to C
Safety
- if the value is allocated, the caller must ensure that the value is eventually freed
Examples found in repository?
39 40 41 42 43 44 45 46 47 48 49 50 51
pub unsafe extern "C" fn uuid_new_v4() -> uuid_t {
// SAFETY:
// - value is not allocated
unsafe { Uuid(uuid::Uuid::new_v4()).return_val() }
}
/// Create a new UUID with the nil value.
#[no_mangle]
pub unsafe extern "C" fn uuid_nil() -> uuid_t {
// SAFETY:
// - value is not allocated
unsafe { Uuid(uuid::Uuid::nil()).return_val() }
}More examples
unsafe fn val_to_arg_out(self, arg_out: *mut Self::CType)
unsafe fn val_to_arg_out(self, arg_out: *mut Self::CType)
Return a value to C, via an “output parameter”.
This is common in functions returning a new value along with some success indication.
Safety
arg_outmust not be NULL and must be properly aligned and pointing to valid memory of the size of CType.
Examples found in repository?
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
pub unsafe extern "C" fn uuid_from_str(s: *const c_char, uuid_out: *mut uuid_t) -> bool {
debug_assert!(!s.is_null());
debug_assert!(!uuid_out.is_null());
// SAFETY:
// - s is valid (see docstring)
let s = unsafe { CStr::from_ptr(s) };
if let Ok(s) = s.to_str() {
if let Ok(u) = uuid::Uuid::parse_str(s) {
// SAFETY:
// - uuid_out is not NULL (see docstring)
// - alignment is not required
unsafe { Uuid::val_to_arg_out(Uuid(u), uuid_out) };
return true;
}
}
false
}