cstring_interop/lib.rs
1//! Code to support calling into C APIs which consume strings.
2
3#![no_std]
4#![warn(missing_docs)]
5
6extern crate alloc;
7
8use alloc::{format, string::String};
9use core::slice::from_raw_parts;
10use rcstring::{CString, Error};
11
12#[inline]
13/// Calls the given function with a lifetime-bound `CString` constructed from
14/// the given `String`.
15pub fn with_cstring<T, E: From<Error>>(
16 s: String,
17 f: impl FnOnce(CString<'_>) -> Result<T, E>,
18) -> Result<T, E> {
19 let string = format!("{}\0", s);
20 f(CString::new(&string)?)
21}
22
23#[inline]
24/// Creates an owned `String` from a given `CString`.
25pub fn from_cstring(cstring: &CString<'_>) -> String {
26 unsafe { from_cstring_raw(cstring.into_raw()) }
27}
28
29/// Creates an owned `String` from a given raw C string pointer.
30///
31/// # Safety
32/// This function assumes that the string is a valid C string with a null
33/// terminator. Passing a pointer which does not refer to such a string will
34/// result in undefined behaviour.
35///
36/// The function does not take responsibility for the C string after reading
37/// from it; managing allocation and lifetime is up to the caller.
38pub unsafe fn from_cstring_raw(cstring: *const libc::c_char) -> String {
39 String::from_utf8_lossy(from_raw_parts(cstring as *const u8, libc::strlen(cstring))).into()
40}