diff options
author | SoniEx2 <endermoneymod@gmail.com> | 2022-08-12 15:29:07 -0300 |
---|---|---|
committer | SoniEx2 <endermoneymod@gmail.com> | 2022-08-12 15:29:07 -0300 |
commit | 0cbd0b9b701c4d067b8dd0fdccc0ebe5c6b6e7e1 (patch) | |
tree | 81bc4c10dd73a94bd1356ce8ba6ce2ddd2ddb27a | |
parent | b76b71507dbd567b2c7f98228783a6dfc8a7bec5 (diff) |
Provide ConstLtPtr to CStr conversion
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/impls/cstr.rs | 64 | ||||
-rw-r--r-- | src/lib.rs | 8 |
3 files changed, 73 insertions, 1 deletions
diff --git a/Cargo.toml b/Cargo.toml index bd6563a..5165718 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ltptr" -version = "0.1.3" +version = "0.1.4" edition = "2021" license = "0BSD" description = "Checked raw pointers." diff --git a/src/impls/cstr.rs b/src/impls/cstr.rs index 5467963..700ae13 100644 --- a/src/impls/cstr.rs +++ b/src/impls/cstr.rs @@ -4,15 +4,79 @@ use std::os::raw::c_char; use crate::*; +/// Conversion from [`CStr`] to [`ConstLtPtr`]. impl AsLtPtr for CStr { + /// The target type of this conversion. type Target = c_char; /// Returns the inner pointer to this C string. /// /// The returned pointer points to a contiguous region of memory terminated /// with a 0 byte to represent the end of the string. + /// + /// # Examples + /// + /// `ltptr` protects you from dangling pointers: (adapted from + /// [`CStr::as_ptr`]) + /// + /// ```rust compile_fail + /// use std::ffi::CString; + /// use ltptr::AsLtPtr; + /// + /// let ptr = CString::new("Hello").unwrap().as_lt_ptr(); + /// unsafe { + /// // would be dangling but the compiler prevents this from compiling + /// ptr.as_raw(); + /// } + /// ``` + /// + /// Which you can fix by adding a binding: + /// + /// ```rust + /// use std::ffi::CString; + /// use ltptr::AsLtPtr; + /// + /// let hello = CString::new("Hello").unwrap(); + /// let ptr = hello.as_lt_ptr(); + /// unsafe { + /// // perfectly fine + /// ptr.as_raw(); + /// } + /// ``` #[inline] fn as_lt_ptr(&self) -> ConstLtPtr<'_, c_char> { unsafe { ConstLtPtr::from_raw(self.as_ptr()) } } } + +/// Conversion from [`ConstLtPtr`] of [`c_char`] to [`CStr`]. +impl FromLtPtr<c_char> for CStr { + /// Wraps a raw C string with a safe C string wrapper. + /// + /// # Safety + /// + /// See [`CStr::from_ptr`] for the safety requirements. + /// + /// # Examples + /// + /// ```rust + /// use std::ffi::CStr; + /// use std::ffi::CString; + /// use std::os::raw::c_char; + /// use ltptr::AsLtPtr; + /// use ltptr::ConstLtPtr; + /// use ltptr::FromLtPtr; + /// + /// unsafe fn foo(ptr: ConstLtPtr<'_, c_char>) { + /// let first = unsafe { CStr::from_lt_ptr(ptr) }.to_str().to_owned(); + /// } + /// + /// let hello = CString::new("Hello").unwrap(); + /// let ptr = hello.as_lt_ptr(); + /// unsafe { foo(ptr) }; + /// ``` + #[inline] + unsafe fn from_lt_ptr(ptr: ConstLtPtr<'_, c_char>) -> &CStr { + unsafe { CStr::from_ptr(ptr.as_raw()) } + } +} diff --git a/src/lib.rs b/src/lib.rs index 90cef27..7ce25cb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: 0BSD #![cfg_attr(not(feature="std"),no_std)] +#![deny(unsafe_op_in_unsafe_fn)] //! This crate provides "checked" raw pointers. //! @@ -107,6 +108,13 @@ pub trait AsLtPtr { fn as_lt_ptr<'a>(&'a self) -> ConstLtPtr<'a, Self::Target>; } +/// Trait for conversion from a [`ConstLtPtr`] of the given `Source` type. +pub trait FromLtPtr<Source> { + /// Returns a value as if by `from_ptr` on a type that implements this, but + /// with a bound lifetime. + unsafe fn from_lt_ptr<'a>(ptr: ConstLtPtr<'a, Source>) -> &'a Self; +} + /// Trait for conversion into a [`MutLtPtr`]. pub trait AsMutLtPtr: AsLtPtr { /// Returns a pointer as if by `as_ptr` on a type that implements this, but |