Skip to content

Commit

Permalink
Merge pull request #1431 from nyurik/as_c_str
Browse files Browse the repository at this point in the history
feat: add `CxxString::as_c_str() -> &CStr`
  • Loading branch information
dtolnay authored Feb 5, 2025
2 parents 8e1e731 + 861252d commit b3aa79f
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/cxx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ const char *cxxbridge1$cxx_string$data(const std::string &s) noexcept {
return s.data();
}

const char *cxxbridge1$cxx_string$c_str(const std::string &s) noexcept {
return s.c_str();
}

std::size_t cxxbridge1$cxx_string$length(const std::string &s) noexcept {
return s.length();
}
Expand Down
8 changes: 8 additions & 0 deletions src/cxx_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use alloc::borrow::Cow;
#[cfg(feature = "alloc")]
use alloc::string::String;
use core::cmp::Ordering;
use core::ffi::c_char;
use core::fmt::{self, Debug, Display};
use core::hash::{Hash, Hasher};
use core::marker::{PhantomData, PhantomPinned};
Expand All @@ -20,6 +21,8 @@ extern "C" {
fn string_destroy(this: &mut MaybeUninit<CxxString>);
#[link_name = "cxxbridge1$cxx_string$data"]
fn string_data(this: &CxxString) -> *const u8;
#[link_name = "cxxbridge1$cxx_string$c_str"]
fn string_c_str(this: &CxxString) -> *const c_char;
#[link_name = "cxxbridge1$cxx_string$length"]
fn string_length(this: &CxxString) -> usize;
#[link_name = "cxxbridge1$cxx_string$clear"]
Expand Down Expand Up @@ -141,6 +144,11 @@ impl CxxString {
str::from_utf8(self.as_bytes())
}

/// Produces a `&CStr` view of the string without additional allocations.
pub fn as_c_str(&self) -> &std::ffi::CStr {
unsafe { std::ffi::CStr::from_ptr(string_c_str(self)) }
}

/// If the contents of the C++ string are valid UTF-8, this function returns
/// a view as a Cow::Borrowed &amp;str. Otherwise replaces any invalid UTF-8
/// sequences with the U+FFFD [replacement character] and returns a
Expand Down
4 changes: 3 additions & 1 deletion tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use cxx::{SharedPtr, UniquePtr};
use cxx_test_suite::module::ffi2;
use cxx_test_suite::{cast, ffi, R};
use std::cell::Cell;
use std::ffi::CStr;
use std::ffi::{CStr, CString};
use std::panic::{self, RefUnwindSafe, UnwindSafe};

thread_local! {
Expand Down Expand Up @@ -54,6 +54,8 @@ fn test_c_return() {
assert_eq!("2020", ffi::c_return_rust_string());
assert_eq!("Hello \u{fffd}World", ffi::c_return_rust_string_lossy());
assert_eq!("2020", ffi::c_return_unique_ptr_string().to_str().unwrap());
// TODO: Use C-string literal c"2020" once MSRV is v1.77+
assert_eq!(CString::new("2020").unwrap().as_c_str(), ffi::c_return_unique_ptr_string().as_c_str());
assert_eq!(4, ffi::c_return_unique_ptr_vector_u8().len());
assert_eq!(
200_u8,
Expand Down

0 comments on commit b3aa79f

Please sign in to comment.