Value

Struct Value 

Source
#[non_exhaustive]
pub struct Value<RType, CType>
where RType: Sized, CType: Sized + From<RType> + Into<RType>,
{ /* private fields */ }
Expand description

Value is used to “pass by value’ semantics.

This is typically used for Copy types, such as integers or enums. For types that are not Copy, crate::Unboxed is a better choice.

The two type parameters must be convertible using Into<RType> for CType and From<RType> for CType. This choice of traits was made deliberately, on the assumption that CType is defined locally to your crate, while RType may be a type from another crate.

§Example

Define your C and Rust types, then a type alias parameterizing Value:

#[repr(C)]
pub struct uuid_t([u8; 16]);

type UuidValue = Value<Uuid, uuid_t>;

Then call static mtehods on that type alias.

Implementations§

Source§

impl<RType, CType> Value<RType, CType>
where RType: Sized, CType: Sized + From<RType> + Into<RType>,

Source

pub fn take(cval: CType) -> RType

Take a CType and return an owned value.

The caller retains a copy of the value.

Examples found in repository?
examples/uuid.rs (line 55)
52pub unsafe extern "C" fn uuid_version(uuid: uuid_t) -> usize {
53    // SAFETY:
54    //  - tcuuid is a valid uuid_t (all byte patterns are valid)
55    let uuid = unsafe { UuidValue::take(uuid) };
56    uuid.get_version_num()
57}
58
59/// Write the string representation of a uuid_t into the given buffer, which must be
60/// at least UUID_STRING_BYTES long.  No NUL terminator is added.
61///
62/// # Safety
63///
64/// * buf must point to at least UUID_STRING_BYTES of valid memory.
65#[no_mangle]
66pub unsafe extern "C" fn uuid_to_buf(tcuuid: uuid_t, buf: *mut c_char) {
67    debug_assert!(!buf.is_null());
68    // SAFETY:
69    //  - buf is valid for len bytes (by C convention)
70    //  - (no alignment requirements for a byte slice)
71    //  - content of buf will not be mutated during the lifetime of this slice (lifetime
72    //    does not outlive this function call)
73    //  - the length of the buffer is less than isize::MAX (see docstring)
74    let buf: &mut [u8] =
75        unsafe { std::slice::from_raw_parts_mut(buf as *mut u8, UUID_STRING_BYTES) };
76    // SAFETY:
77    //  - tcuuid is a valid uuid_t (all byte patterns are valid)
78    let uuid = unsafe { UuidValue::take(tcuuid) };
79    uuid.as_hyphenated().encode_lower(buf);
80}
Source

pub fn return_val(rval: RType) -> CType

Return a CType containing rval, moving rval in the process.

Examples found in repository?
examples/uuid.rs (line 39)
36pub unsafe extern "C" fn uuid_new_v4() -> uuid_t {
37    // SAFETY:
38    // - value is not allocated
39    unsafe { UuidValue::return_val(uuid::Uuid::new_v4()) }
40}
41
42/// Create a new UUID with the nil value.
43#[no_mangle]
44pub unsafe extern "C" fn uuid_nil() -> uuid_t {
45    // SAFETY:
46    // - value is not allocated
47    unsafe { UuidValue::return_val(uuid::Uuid::nil()) }
48}
More examples
Hide additional examples
examples/status.rs (line 237)
228pub unsafe extern "C" fn hittr_system_status(system: *const System) -> hittr_status_t {
229    // SAFETY:
230    // - system is not NULL and valid (see docstring)
231    // - system is valid for the life of this function (documented as not threadsafe)
232    // - system will not be modified during the life of this function (documented as not threadsafe)
233    unsafe {
234        BoxedSystem::with_ref_nonnull(system, |system| {
235            // SAFETY:
236            // - hittr_status_t is not allocated, so no issues
237            unsafe { StatusValue::return_val(system.status) }
238        })
239    }
240}
Source

pub unsafe fn to_out_param(rval: RType, arg_out: *mut CType)

Initialize the value pointed to arg_out with rval, “moving” rval into the pointer.

If the pointer is NULL, rval is dropped. Use Value::to_out_param_nonnull to panic in this situation.

§Safety
  • if arg_out is not NULL, then it must be aligned for and have enough space for CType.
Examples found in repository?
examples/uuid.rs (line 102)
91pub unsafe extern "C" fn uuid_from_str(s: *const c_char, uuid_out: *mut uuid_t) -> bool {
92    debug_assert!(!s.is_null());
93    debug_assert!(!uuid_out.is_null());
94    // SAFETY:
95    //  - s is valid (see docstring)
96    let s = unsafe { CStr::from_ptr(s) };
97    if let Ok(s) = s.to_str() {
98        if let Ok(u) = uuid::Uuid::parse_str(s) {
99            // SAFETY:
100            //  - uuid_out is not NULL (see docstring)
101            //  - alignment is not required
102            unsafe { UuidValue::to_out_param(u, uuid_out) };
103            return true;
104        }
105    }
106    false
107}
Source

pub unsafe fn to_out_param_nonnull(rval: RType, arg_out: *mut CType)

Initialize the value pointed to arg_out with rval, “moving” rval into the pointer.

If the pointer is NULL, this method will panic.

§Safety
  • arg_out must not be NULL, must be aligned for CType and have enough space for CType.

Auto Trait Implementations§

§

impl<RType, CType> Freeze for Value<RType, CType>

§

impl<RType, CType> RefUnwindSafe for Value<RType, CType>
where RType: RefUnwindSafe, CType: RefUnwindSafe,

§

impl<RType, CType> Send for Value<RType, CType>
where RType: Send, CType: Send,

§

impl<RType, CType> Sync for Value<RType, CType>
where RType: Sync, CType: Sync,

§

impl<RType, CType> Unpin for Value<RType, CType>
where RType: Unpin, CType: Unpin,

§

impl<RType, CType> UnwindSafe for Value<RType, CType>
where RType: UnwindSafe, CType: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.