Module traits

Module traits 

Source
Expand description

Traits required by fmt! macro.

fmt! needs to convert values from Rust types like u64 and String to C types like uint64_t and const char*.

For integer types, this happens automatically, e.g. u64 can be passed directly into libc::snprintf.

Floating-point types are a bit more complicated: f32 (C’s float) has to be converted to f64 (C’s double) because that’s how variadic FFI works. f64 can be passed over FFI without any problems.

Strings are the most complicated of all: Rust represents them as an array of bytes, whereas C represents them as a chunk of memory terminated by a null byte. As a result, converting a String into const char* requires an allocation to temporarily store a string in a C-compatible fashion. snprintf doesn’t understand Rust’s borrowing, so we also need a Rust object to hold that memory while snprintf works with a pointer to it.

To support all of this, fmt! uses a two-stage process:

  1. convert a Rust type into an intermediate “holder” that owns a C-compatible representation of that value (Printfable trait);
  2. borrow the C-compatible representation of the value from the “holder” (CReprHolder trait).

For example, a “holder” for a String is std::ffi::CString. It can be borrowed to call its to_ptr method that returns *const libc::c_char.

For numeric types, the holder is the same as the type itself, and the values are simply copied. For example, u64’s “holder” is u64, which is then borrowed to get a u64 again.

Traits§

CReprHolder
Trait of all types that hold a C representation of a value.
Printfable
Trait of all types that can be formatted with fmt! macro.