facet_core/impls_alloc/
vec.rs

1use crate::*;
2use core::hash::Hash as _;
3
4use alloc::vec::Vec;
5
6unsafe impl<'a, T> Facet<'a> for Vec<T>
7where
8    T: Facet<'a>,
9{
10    const VTABLE: &'static ValueVTable = &const {
11        let mut builder = ValueVTable::builder::<Self>()
12            .type_name(|f, opts| {
13                if let Some(opts) = opts.for_children() {
14                    write!(f, "Vec<")?;
15                    (T::SHAPE.vtable.type_name)(f, opts)?;
16                    write!(f, ">")
17                } else {
18                    write!(f, "Vec<⋯>")
19                }
20            })
21            .default_in_place(|target| unsafe { target.put(Self::default()) });
22
23        if T::SHAPE.vtable.clone_into.is_some() {
24            builder = builder.clone_into(|src, dst| unsafe {
25                let mut new_vec = Vec::with_capacity(src.len());
26
27                let t_clone_into = <VTableView<T>>::of().clone_into().unwrap();
28
29                for item in src {
30                    use crate::TypedPtrUninit;
31                    use core::mem::MaybeUninit;
32
33                    let mut new_item = MaybeUninit::<T>::uninit();
34                    let uninit_item = TypedPtrUninit::new(new_item.as_mut_ptr());
35
36                    (t_clone_into)(item, uninit_item);
37
38                    new_vec.push(new_item.assume_init());
39                }
40
41                dst.put(new_vec)
42            });
43        }
44
45        if T::SHAPE.vtable.debug.is_some() {
46            builder = builder.debug(|value, f| {
47                write!(f, "[")?;
48                for (i, item) in value.iter().enumerate() {
49                    if i > 0 {
50                        write!(f, ", ")?;
51                    }
52                    (<VTableView<T>>::of().debug().unwrap())(item, f)?;
53                }
54                write!(f, "]")
55            });
56        }
57
58        if T::SHAPE.vtable.eq.is_some() {
59            builder = builder.eq(|a, b| {
60                if a.len() != b.len() {
61                    return false;
62                }
63                for (item_a, item_b) in a.iter().zip(b.iter()) {
64                    if !(<VTableView<T>>::of().eq().unwrap())(item_a, item_b) {
65                        return false;
66                    }
67                }
68                true
69            });
70        }
71
72        if T::SHAPE.vtable.hash.is_some() {
73            builder = builder.hash(|vec, hasher_this, hasher_write_fn| unsafe {
74                use crate::HasherProxy;
75                let t_hash = <VTableView<T>>::of().hash().unwrap_unchecked();
76                let mut hasher = HasherProxy::new(hasher_this, hasher_write_fn);
77                vec.len().hash(&mut hasher);
78                for item in vec {
79                    (t_hash)(item, hasher_this, hasher_write_fn);
80                }
81            });
82        }
83
84        let traits = MarkerTraits::SEND
85            .union(MarkerTraits::SYNC)
86            .union(MarkerTraits::EQ)
87            .union(MarkerTraits::UNPIN)
88            .intersection(T::SHAPE.vtable.marker_traits);
89        builder = builder.marker_traits(traits);
90
91        builder.build()
92    };
93
94    const SHAPE: &'static Shape = &const {
95        Shape::builder_for_sized::<Self>()
96            .type_params(&[TypeParam {
97                name: "T",
98                shape: || T::SHAPE,
99            }])
100            .ty(Type::User(UserType::Opaque))
101            .def(Def::List(
102                ListDef::builder()
103                    .vtable(
104                        &const {
105                            ListVTable::builder()
106                                .init_in_place_with_capacity(|data, capacity| unsafe {
107                                    data.put(Self::with_capacity(capacity))
108                                })
109                                .push(|ptr, item| unsafe {
110                                    let vec = ptr.as_mut::<Self>();
111                                    let item = item.read::<T>();
112                                    (*vec).push(item);
113                                })
114                                .len(|ptr| unsafe {
115                                    let vec = ptr.get::<Self>();
116                                    vec.len()
117                                })
118                                .as_ptr(|ptr| unsafe {
119                                    let vec = ptr.get::<Self>();
120                                    PtrConst::new(vec.as_ptr())
121                                })
122                                .as_mut_ptr(|ptr| unsafe {
123                                    let vec = ptr.as_mut::<Self>();
124                                    PtrMut::new(vec.as_mut_ptr())
125                                })
126                                .build()
127                        },
128                    )
129                    .t(|| T::SHAPE)
130                    .build(),
131            ))
132            .build()
133    };
134}