printf-wrap
is a Rust crate with types to help developers write safe wrappers for
C functions using printf(3)
-style format strings and varargs.
In particular, PrintfFmt<(T_1, T_2, ..., T_N)>
is a wrapper around a null-terminated string
that is guaranteed to be a valid format string for use with N
arguments of types
T_1
, T_2
, …, T_N
when the arguments are mapped through the PrintfArgument::as_c_val()
method.
The following example shows a safe wrapper for calling printf
with two arguments,
along with a use of it.
use printf_wrap::{PrintfFmt, PrintfArgument};
use libc::{c_int, printf};
/// Safe wrapper for calling printf with two value arguments.
pub fn printf_with_2_args<T, U>(fmt: PrintfFmt<(T, U)>, arg1: T, arg2: U) -> c_int
where
T: PrintfArgument,
U: PrintfArgument,
{
unsafe { printf(fmt.as_ptr(), arg1.as_c_val(), arg2.as_c_val()) }
}
const MY_FORMAT_STRING: PrintfFmt<(u32, i32)> =
PrintfFmt::new_or_panic("unsigned = %u, signed = %d\0");
fn main() {
printf_with_2_args(MY_FORMAT_STRING, 42, -7);
}
In the example, MY_FORMAT_STRING
is determined to be a valid format string
for arguments of (u32, i32)
at compile time, with zero runtime overhead.
With a little macro magic, generating wrappers for different numbers of post-format
arguments is easy, with printf-wrap
handling the validation and conversion of
values to C-compatible equivalents.
libc
– enables support relating to the C types
size_t
, intmax_t
, and ptrdiff_t
; requires the libc
crate.
example
– enables a demonstration of the use of printf-wrap
with some wrappers around functions from the C standard library; also
requires the libc
crate.
This crate is licensed under either of the MIT license or the Apache License version 2.0 at your option.