mirror of
https://github.com/chatmail/core.git
synced 2026-05-02 21:06:31 +03:00
Add .strdup() method to Option<AsRef<str>>
We already have a .strdup() method on AsRef<str>, this adds this method also to an option of this. In case the option is None a NULL pointer is returned. This is done by using a new trait, as the type system otherwise considers such an implementation conflicting with the existing one.
This commit is contained in:
committed by
holger krekel
parent
2977ceb459
commit
e2f1ea1444
@@ -3227,7 +3227,7 @@ pub unsafe extern "C" fn dc_lot_get_text1(lot: *mut dc_lot_t) -> *mut libc::c_ch
|
|||||||
}
|
}
|
||||||
|
|
||||||
let lot = &*lot;
|
let lot = &*lot;
|
||||||
strdup_opt(lot.get_text1())
|
lot.get_text1().strdup()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -3238,7 +3238,7 @@ pub unsafe extern "C" fn dc_lot_get_text2(lot: *mut dc_lot_t) -> *mut libc::c_ch
|
|||||||
}
|
}
|
||||||
|
|
||||||
let lot = &*lot;
|
let lot = &*lot;
|
||||||
strdup_opt(lot.get_text2())
|
lot.get_text2().strdup()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -3323,13 +3323,6 @@ impl<T: Default, E: std::fmt::Display> ResultExt<T, E> for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn strdup_opt(s: Option<impl AsRef<str>>) -> *mut libc::c_char {
|
|
||||||
match s {
|
|
||||||
Some(s) => s.as_ref().strdup(),
|
|
||||||
None => ptr::null_mut(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait ResultNullableExt<T> {
|
trait ResultNullableExt<T> {
|
||||||
fn into_raw(self) -> *mut T;
|
fn into_raw(self) -> *mut T;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use failure::Fail;
|
use failure::Fail;
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
/// Duplicates a string
|
/// Duplicates a string
|
||||||
///
|
///
|
||||||
@@ -144,7 +145,7 @@ pub trait CStringExt {
|
|||||||
|
|
||||||
impl CStringExt for CString {}
|
impl CStringExt for CString {}
|
||||||
|
|
||||||
/// Convenience methods to make transitioning from raw C strings easier.
|
/// Convenience methods to turn strings into C strings.
|
||||||
///
|
///
|
||||||
/// To interact with (legacy) C APIs we often need to convert from
|
/// To interact with (legacy) C APIs we often need to convert from
|
||||||
/// Rust strings to raw C strings. This can be clumsy to do correctly
|
/// Rust strings to raw C strings. This can be clumsy to do correctly
|
||||||
@@ -174,6 +175,35 @@ impl<T: AsRef<str>> StrExt for T {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convenience methods to turn optional strings into C strings.
|
||||||
|
///
|
||||||
|
/// This is the same as the [StrExt] trait but a different trait name
|
||||||
|
/// to work around the type system not allowing to implement [StrExt]
|
||||||
|
/// for `Option<impl StrExt>` When we already have an [StrExt] impl
|
||||||
|
/// for `AsRef<&str>`.
|
||||||
|
///
|
||||||
|
/// When the [Option] is [Option::Some] this behaves just like
|
||||||
|
/// [StrExt::strdup], when it is [Option::None] a null pointer is
|
||||||
|
/// returned.
|
||||||
|
pub trait OptStrExt {
|
||||||
|
/// Allocate a new raw C `*char` version of this string, or NULL.
|
||||||
|
///
|
||||||
|
/// See [StrExt::strdup] for details.
|
||||||
|
unsafe fn strdup(&self) -> *mut libc::c_char;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: AsRef<str>> OptStrExt for Option<T> {
|
||||||
|
unsafe fn strdup(&self) -> *mut libc::c_char {
|
||||||
|
match self {
|
||||||
|
Some(s) => {
|
||||||
|
let tmp = CString::yolo(s.as_ref());
|
||||||
|
dc_strdup(tmp.as_ptr())
|
||||||
|
}
|
||||||
|
None => ptr::null_mut(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn to_string_lossy(s: *const libc::c_char) -> String {
|
pub fn to_string_lossy(s: *const libc::c_char) -> String {
|
||||||
if s.is_null() {
|
if s.is_null() {
|
||||||
return "".into();
|
return "".into();
|
||||||
@@ -347,4 +377,19 @@ mod tests {
|
|||||||
assert_eq!(cmp, 0);
|
assert_eq!(cmp, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_strdup_opt_string() {
|
||||||
|
unsafe {
|
||||||
|
let s = Some("hello");
|
||||||
|
let c = s.strdup();
|
||||||
|
let cmp = strcmp(c, b"hello\x00" as *const u8 as *const libc::c_char);
|
||||||
|
free(c as *mut libc::c_void);
|
||||||
|
assert_eq!(cmp, 0);
|
||||||
|
|
||||||
|
let s: Option<&str> = None;
|
||||||
|
let c = s.strdup();
|
||||||
|
assert_eq!(c, ptr::null_mut());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user