serde_yaml/libyaml/
util.rs

1use std::marker::PhantomData;
2use std::mem::{self, MaybeUninit};
3use std::ops::Deref;
4use std::ptr::{addr_of, NonNull};
5
6pub(crate) struct Owned<T, Init = T> {
7    ptr: NonNull<T>,
8    marker: PhantomData<NonNull<Init>>,
9}
10
11impl<T> Owned<T> {
12    pub fn new_uninit() -> Owned<MaybeUninit<T>, T> {
13        // FIXME: use Box::new_uninit when stable
14        let boxed = Box::new(MaybeUninit::<T>::uninit());
15        Owned {
16            ptr: unsafe { NonNull::new_unchecked(Box::into_raw(boxed)) },
17            marker: PhantomData,
18        }
19    }
20
21    pub unsafe fn assume_init(definitely_init: Owned<MaybeUninit<T>, T>) -> Owned<T> {
22        let ptr = definitely_init.ptr;
23        mem::forget(definitely_init);
24        Owned {
25            ptr: ptr.cast(),
26            marker: PhantomData,
27        }
28    }
29}
30
31#[repr(transparent)]
32pub(crate) struct InitPtr<T> {
33    pub ptr: *mut T,
34}
35
36impl<T, Init> Deref for Owned<T, Init> {
37    type Target = InitPtr<Init>;
38
39    fn deref(&self) -> &Self::Target {
40        unsafe { &*addr_of!(self.ptr).cast::<InitPtr<Init>>() }
41    }
42}
43
44impl<T, Init> Drop for Owned<T, Init> {
45    fn drop(&mut self) {
46        let _ = unsafe { Box::from_raw(self.ptr.as_ptr()) };
47    }
48}