| @@ -19,26 +19,33 @@ use core::{ · 18 unmodified lines |
| 19 | /// This trait is meant to be used in cases when Rust objects are stored in C objects and | 19 | /// This trait is meant to be used in cases when Rust objects are stored in C objects and |
| 20 | /// eventually "freed" back to Rust. | 20 | /// eventually "freed" back to Rust. |
| 21 | pub trait ForeignOwnable: Sized { | 21 | pub trait ForeignOwnable: Sized { |
| 22 | /// Type of values borrowed between calls to [`ForeignOwnable::into_foreign`] and | 22 | /// Type used to immutably borrow a value that is currently foreign-owned. |
| 23 | /// [`ForeignOwnable::from_foreign`]. | | |
| 24 | type Borrowed<'a>; | 23 | type Borrowed<'a>; |
| 25 | | 24 | |
| | 25 | /// Type used to mutably borrow a value that is currently foreign-owned. |
| | 26 | type BorrowedMut<'a>; |
| | 27 | |
| 26 | /// Converts a Rust-owned object to a foreign-owned one. | 28 | /// Converts a Rust-owned object to a foreign-owned one. |
| 27 | /// | 29 | /// |
| 28 | /// The foreign representation is a pointer to void. There are no guarantees for this pointer. | 30 | /// The foreign representation is a pointer to void. There are no guarantees for this pointer. |
| 29 | /// For example, it might be invalid, dangling or pointing to uninitialized memory. Using it in | 31 | /// For example, it might be invalid, dangling or pointing to uninitialized memory. Using it in |
| 30 | /// any way except for [`ForeignOwnable::from_foreign`], [`ForeignOwnable::borrow`], | 32 | /// any way except for [`from_foreign`], [`try_from_foreign`], [`borrow`], or [`borrow_mut`] can |
| 31 | /// [`ForeignOwnable::try_from_foreign`] can result in undefined behavior. | 33 | /// result in undefined behavior. |
| | 34 | /// |
| | 35 | /// [`from_foreign`]: Self::from_foreign |
| | 36 | /// [`try_from_foreign`]: Self::try_from_foreign |
| | 37 | /// [`borrow`]: Self::borrow |
| | 38 | /// [`borrow_mut`]: Self::borrow_mut |
| 32 | fn into_foreign(self) -> *mut crate::ffi::c_void; | 39 | fn into_foreign(self) -> *mut crate::ffi::c_void; |
| 33 | | 40 | |
| 34 | /// Converts a foreign-owned object back to a Rust-owned one. | 41 | /// Converts a foreign-owned object back to a Rust-owned one. |
| 35 | /// | 42 | /// |
| 36 | /// # Safety | 43 | /// # Safety |
| 37 | /// | 44 | /// |
| 38 | /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for | 45 | /// The provided pointer must have been returned by a previous call to [`into_foreign`], and it |
| 39 | /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet. | 46 | /// must not be passed to `from_foreign` more than once. |
| 40 | /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] for | 47 | /// |
| 41 | /// this object must have been dropped. | 48 | /// [`into_foreign`]: Self::into_foreign |
| 42 | unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self; | 49 | unsafe fn from_foreign(ptr: *mut crate::ffi::c_void) -> Self; |
| 43 | | 50 | |
| 44 | /// Tries to convert a foreign-owned object back to a Rust-owned one. | 51 | /// Tries to convert a foreign-owned object back to a Rust-owned one. |
| @@ -48,8 +55,9 @@ pub trait ForeignOwnable: Sized { · 3 unmodified lines |
| 48 | /// | 55 | /// |
| 49 | /// # Safety | 56 | /// # Safety |
| 50 | /// | 57 | /// |
| 51 | /// `ptr` must either be null or satisfy the safety requirements for | 58 | /// `ptr` must either be null or satisfy the safety requirements for [`from_foreign`]. |
| 52 | /// [`ForeignOwnable::from_foreign`]. | 59 | /// |
| | 60 | /// [`from_foreign`]: Self::from_foreign |
| 53 | unsafe fn try_from_foreign(ptr: *mut crate::ffi::c_void) -> Option<Self> { | 61 | unsafe fn try_from_foreign(ptr: *mut crate::ffi::c_void) -> Option<Self> { |
| 54 | if ptr.is_null() { | 62 | if ptr.is_null() { |
| 55 | None | 63 | None |
| @@ -60,17 +68,53 @@ pub trait ForeignOwnable: Sized { · 4 unmodified lines |
| 60 | } | 68 | } |
| 61 | } | 69 | } |
| 62 | | 70 | |
| 63 | /// Borrows a foreign-owned object. | 71 | /// Borrows a foreign-owned object immutably. |
| | 72 | /// |
| | 73 | /// This method provides a way to access a foreign-owned value from Rust immutably. It provides |
| | 74 | /// you with exactly the same abilities as an `&Self` when the value is Rust-owned. |
| 64 | /// | 75 | /// |
| 65 | /// # Safety | 76 | /// # Safety |
| 66 | /// | 77 | /// |
| 67 | /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for | 78 | /// The provided pointer must have been returned by a previous call to [`into_foreign`], and if |
| 68 | /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet. | 79 | /// the pointer is ever passed to [`from_foreign`], then that call must happen after the end of |
| | 80 | /// the lifetime 'a. |
| | 81 | /// |
| | 82 | /// [`into_foreign`]: Self::into_foreign |
| | 83 | /// [`from_foreign`]: Self::from_foreign |
| 69 | unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Self::Borrowed<'a>; | 84 | unsafe fn borrow<'a>(ptr: *mut crate::ffi::c_void) -> Self::Borrowed<'a>; |
| | 85 | |
| | 86 | /// Borrows a foreign-owned object mutably. |
| | 87 | /// |
| | 88 | /// This method provides a way to access a foreign-owned value from Rust mutably. It provides |
| | 89 | /// you with exactly the same abilities as an `&mut Self` when the value is Rust-owned, except |
| | 90 | /// that the address of the object must not be changed. |
| | 91 | /// |
| | 92 | /// Note that for types like [`Arc`], an `&mut Arc<T>` only gives you immutable access to the |
| | 93 | /// inner value, so this method also only provides immutable access in that case. |
| | 94 | /// |
| | 95 | /// In the case of `Box<T>`, this method gives you the ability to modify the inner `T`, but it |
| | 96 | /// does not let you change the box itself. That is, you cannot change which allocation the box |
| | 97 | /// points at. |
| | 98 | /// |
| | 99 | /// # Safety |
| | 100 | /// |
| | 101 | /// The provided pointer must have been returned by a previous call to [`into_foreign`], and if |
| | 102 | /// the pointer is ever passed to [`from_foreign`], then that call must happen after the end of |
| | 103 | /// the lifetime 'a. |
| | 104 | /// |
| | 105 | /// The lifetime 'a must not overlap with the lifetime of any other call to [`borrow`] or |
| | 106 | /// `borrow_mut` on the same object. |
| | 107 | /// |
| | 108 | /// [`into_foreign`]: Self::into_foreign |
| | 109 | /// [`from_foreign`]: Self::from_foreign |
| | 110 | /// [`borrow`]: Self::borrow |
| | 111 | /// [`Arc`]: crate::sync::Arc |
| | 112 | unsafe fn borrow_mut<'a>(ptr: *mut crate::ffi::c_void) -> Self::BorrowedMut<'a>; |
| 70 | } | 113 | } |
| 71 | | 114 | |
| 72 | impl ForeignOwnable for () { | 115 | impl ForeignOwnable for () { |
| 73 | type Borrowed<'a> = (); | 116 | type Borrowed<'a> = (); |
| | 117 | type BorrowedMut<'a> = (); |
| 74 | | 118 | |
| 75 | fn into_foreign(self) -> *mut crate::ffi::c_void { | 119 | fn into_foreign(self) -> *mut crate::ffi::c_void { |
| 76 | core::ptr::NonNull::dangling().as_ptr() | 120 | core::ptr::NonNull::dangling().as_ptr() |
| @@ -79,6 +123,7 @@ impl ForeignOwnable for () { · 2 unmodified lines |
| 79 | unsafe fn from_foreign(_: *mut crate::ffi::c_void) -> Self {} | 123 | unsafe fn from_foreign(_: *mut crate::ffi::c_void) -> Self {} |
| 80 | | 124 | |
| 81 | unsafe fn borrow<'a>(_: *mut crate::ffi::c_void) -> Self::Borrowed<'a> {} | 125 | unsafe fn borrow<'a>(_: *mut crate::ffi::c_void) -> Self::Borrowed<'a> {} |
| | 126 | unsafe fn borrow_mut<'a>(_: *mut crate::ffi::c_void) -> Self::BorrowedMut<'a> {} |
| 82 | } | 127 | } |
| 83 | | 128 | |
| 84 | /// Runs a cleanup function/closure when dropped. | 129 | /// Runs a cleanup function/closure when dropped. |