Minor changes

This commit is contained in:
topjohnwu 2023-06-23 01:50:33 -07:00
parent fbd1dbb20c
commit 279f955a84

View File

@ -4,7 +4,7 @@ use std::fmt::{Arguments, Debug, Display, Formatter};
use std::ops::Deref; use std::ops::Deref;
use std::path::Path; use std::path::Path;
use std::str::Utf8Error; use std::str::Utf8Error;
use std::{fmt, io, slice, str}; use std::{fmt, io, mem, slice, str};
use libc::c_char; use libc::c_char;
use thiserror::Error; use thiserror::Error;
@ -141,7 +141,7 @@ impl Utf8CStr {
#[inline] #[inline]
pub unsafe fn from_bytes_unchecked(buf: &[u8]) -> &Utf8CStr { pub unsafe fn from_bytes_unchecked(buf: &[u8]) -> &Utf8CStr {
&*(buf as *const [u8] as *const Utf8CStr) mem::transmute(buf)
} }
pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> Result<&'a Utf8CStr, StrErr> { pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> Result<&'a Utf8CStr, StrErr> {
@ -169,7 +169,8 @@ impl Utf8CStr {
#[inline] #[inline]
pub fn as_cstr(&self) -> &CStr { pub fn as_cstr(&self) -> &CStr {
self.as_ref() // SAFETY: Already validated as null terminated during construction
unsafe { CStr::from_bytes_with_nul_unchecked(&self.inner) }
} }
} }
@ -178,7 +179,8 @@ impl Deref for Utf8CStr {
#[inline] #[inline]
fn deref(&self) -> &str { fn deref(&self) -> &str {
self.as_ref() // SAFETY: Already UTF-8 validated during construction
unsafe { str::from_utf8_unchecked(self.as_bytes()) }
} }
} }
@ -199,16 +201,14 @@ impl Debug for Utf8CStr {
impl AsRef<CStr> for Utf8CStr { impl AsRef<CStr> for Utf8CStr {
#[inline] #[inline]
fn as_ref(&self) -> &CStr { fn as_ref(&self) -> &CStr {
// SAFETY: Already validated as null terminated during construction self.as_cstr()
unsafe { CStr::from_bytes_with_nul_unchecked(&self.inner) }
} }
} }
impl AsRef<str> for Utf8CStr { impl AsRef<str> for Utf8CStr {
#[inline] #[inline]
fn as_ref(&self) -> &str { fn as_ref(&self) -> &str {
// SAFETY: Already UTF-8 validated during construction self.deref()
unsafe { str::from_utf8_unchecked(self.as_bytes()) }
} }
} }
@ -312,38 +312,49 @@ where
} }
} }
impl<T: Copy> FlatData for T {} macro_rules! impl_flat_data {
($($t:ty)*) => ($(impl FlatData for $t {})*)
}
// Check libc return value and map errors to Result impl_flat_data!(usize u8 u16 u32 u64 isize i8 i16 i32 i64);
pub trait LibcReturn: Copy {
// Check libc return value and map to Result
pub trait LibcReturn
where
Self: Copy,
{
fn is_error(&self) -> bool; fn is_error(&self) -> bool;
fn check_os_err(self) -> io::Result<Self> { fn check_os_err(self) -> io::Result<Self> {
if self.is_error() { if self.is_error() {
return Err(io::Error::last_os_error()); Err(io::Error::last_os_error())
} else {
Ok(self)
} }
Ok(self)
} }
} }
impl LibcReturn for i32 { macro_rules! impl_libc_return {
fn is_error(&self) -> bool { ($($t:ty)*) => ($(
*self < 0 impl LibcReturn for $t {
} #[inline]
fn is_error(&self) -> bool {
*self < 0
}
}
)*)
} }
impl LibcReturn for isize { impl_libc_return! { i8 i16 i32 i64 isize }
fn is_error(&self) -> bool {
*self < 0
}
}
impl<T> LibcReturn for *const T { impl<T> LibcReturn for *const T {
#[inline]
fn is_error(&self) -> bool { fn is_error(&self) -> bool {
self.is_null() self.is_null()
} }
} }
impl<T> LibcReturn for *mut T { impl<T> LibcReturn for *mut T {
#[inline]
fn is_error(&self) -> bool { fn is_error(&self) -> bool {
self.is_null() self.is_null()
} }