dst_container/
lib.rs

1//! This is a crate providing functionalities creating DST instances.
2
3#![feature(allocator_api)]
4#![feature(layout_for_ptr)]
5#![feature(maybe_uninit_write_slice)]
6#![feature(ptr_metadata)]
7#![feature(slice_index_methods)]
8#![feature(slice_ptr_get)]
9#![feature(specialization)]
10#![cfg_attr(test, feature(new_zeroed_alloc, test))]
11#![allow(incomplete_features)]
12#![warn(missing_docs)]
13
14#[cfg(test)]
15extern crate test;
16
17use std::{mem::MaybeUninit, ptr::Pointee};
18
19#[doc(no_inline)]
20pub use dst_container_derive::{MaybeUninitProject, UnsizedClone};
21
22mod smart_ptr;
23pub use smart_ptr::{AssumeInit, NewUninit, SmartPtr};
24
25mod unsized_slice;
26pub use unsized_slice::UnsizedSlice;
27
28mod unsized_str;
29pub use unsized_str::UnsizedStr;
30
31mod fixed_vec;
32pub use fixed_vec::FixedVec;
33
34/// A DST with maybe-uninit project defined.
35pub trait MaybeUninitProject {
36    /// The maybe-uninit project type.
37    /// [`MaybeUninit`] can only deal with [`Sized`] types.
38    type Target: ?Sized + Pointee<Metadata = <Self as Pointee>::Metadata>;
39}
40
41impl<T: Sized> MaybeUninitProject for T {
42    type Target = MaybeUninit<T>;
43}
44
45impl<T> MaybeUninitProject for [T] {
46    type Target = [MaybeUninit<T>];
47}
48
49impl MaybeUninitProject for str {
50    type Target = [MaybeUninit<u8>];
51}
52
53/// Provide the ability to duplicate a DST object.
54pub trait UnsizedClone: MaybeUninitProject {
55    /// Clone the current type to maybe-uninit target.
56    fn clone_to(&self, dest: &mut Self::Target);
57
58    /// Returns a boxed copy of the boxed value.
59    ///
60    /// Only apply to [`Box`] because [`Rc`] and [`Arc`] have own clone impl.
61    ///
62    /// [`Rc`]: std::rc::Rc
63    /// [`Arc`]: std::sync::Arc
64    #[allow(clippy::borrowed_box)]
65    fn clone(self: &Box<Self>) -> Box<Self> {
66        let (_, metadata) = (self.as_ref() as *const Self).to_raw_parts();
67        unsafe { Box::<Self>::new_unsized_with(metadata, |dest| self.as_ref().clone_to(dest)) }
68    }
69}
70
71impl<T: Clone> UnsizedClone for T {
72    fn clone_to(&self, dest: &mut Self::Target) {
73        dest.write(self.clone());
74    }
75}
76
77impl<T: UnsizedClone> UnsizedClone for [T] {
78    default fn clone_to(&self, _dest: &mut Self::Target) {
79        // All Sized Clone implements UnsizedClone.
80        unreachable!()
81    }
82}
83
84impl<T: Clone> UnsizedClone for [T] {
85    default fn clone_to(&self, dest: &mut Self::Target) {
86        dest.write_clone_of_slice(self);
87    }
88}
89
90impl<T: Copy> UnsizedClone for [T] {
91    fn clone_to(&self, dest: &mut Self::Target) {
92        dest.write_clone_of_slice(self);
93    }
94}
95
96impl UnsizedClone for str {
97    fn clone_to(&self, dest: &mut Self::Target) {
98        dest.write_clone_of_slice(self.as_bytes());
99    }
100}