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