foreign_types_shared/lib.rs
1//! Internal crate used by foreign-types
2
3#![no_std]
4#![warn(missing_docs)]
5#![doc(html_root_url = "https://docs.rs/foreign-types-shared/0.3")]
6
7use core::cell::UnsafeCell;
8use core::marker::PhantomData;
9use core::mem;
10
11/// An opaque type used to define `ForeignTypeRef` types.
12///
13/// A type implementing `ForeignTypeRef` should simply be a newtype wrapper around this type.
14pub struct Opaque(PhantomData<UnsafeCell<*mut ()>>);
15
16/// A type implemented by wrappers over foreign types.
17///
18/// # Safety
19///
20/// Implementations of `ForeignType` must guarantee the following:
21/// - `Self::from_ptr(x).as_ptr() == x`
22/// - `Self::from_ptr(x).into_ptr(x) == x`
23/// - `Self::from_ptr(x).deref().as_ptr(x) == x`
24/// - `Self::from_ptr(x).deref_mut().as_ptr(x) == x`
25/// - `Self::from_ptr(x).as_ref().as_ptr(x) == x`
26/// - `Self::from_ptr(x).as_mut().as_ptr(x) == x`
27pub unsafe trait ForeignType: Sized {
28 /// The raw C type.
29 type CType;
30
31 /// The type representing a reference to this type.
32 type Ref: ForeignTypeRef<CType = Self::CType>;
33
34 /// Constructs an instance of this type from its raw type.
35 ///
36 /// # Safety
37 ///
38 /// `ptr` must be a valid, owned instance of the native type.
39 unsafe fn from_ptr(ptr: *mut Self::CType) -> Self;
40
41 /// Returns a raw pointer to the wrapped value.
42 fn as_ptr(&self) -> *mut Self::CType;
43
44 /// Consumes the wrapper and returns the raw pointer.
45 #[inline]
46 fn into_ptr(self) -> *mut Self::CType {
47 let ptr = self.as_ptr();
48 mem::forget(self);
49 ptr
50 }
51}
52
53/// A trait implemented by types which reference borrowed foreign types.
54///
55/// # Safety
56///
57/// Implementations of `ForeignTypeRef` must guarantee the following:
58///
59/// - `Self::from_ptr(x).as_ptr() == x`
60/// - `Self::from_mut_ptr(x).as_ptr() == x`
61pub unsafe trait ForeignTypeRef: Sized {
62 /// The raw C type.
63 type CType;
64
65 /// Constructs a shared instance of this type from its raw type.
66 ///
67 /// # Safety
68 ///
69 /// `ptr` must be a valid, immutable, instance of the type for the `'a` lifetime.
70 #[inline]
71 unsafe fn from_ptr<'a>(ptr: *mut Self::CType) -> &'a Self {
72 debug_assert!(!ptr.is_null());
73 &*(ptr as *mut _)
74 }
75
76 /// Constructs a mutable reference of this type from its raw type.
77 ///
78 /// # Safety
79 ///
80 /// `ptr` must be a valid, unique, instance of the type for the `'a` lifetime.
81 #[inline]
82 unsafe fn from_ptr_mut<'a>(ptr: *mut Self::CType) -> &'a mut Self {
83 debug_assert!(!ptr.is_null());
84 &mut *(ptr as *mut _)
85 }
86
87 /// Returns a raw pointer to the wrapped value.
88 #[inline]
89 fn as_ptr(&self) -> *mut Self::CType {
90 self as *const _ as *mut _
91 }
92}