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                    // FIXME: THIS IS VERY WRONG
32                        .clone_into(|src, dst| unsafe { dst.put(core::ptr::read(src)) });
33
34                    if T::SHAPE.vtable.debug.is_some() {
35                        builder = builder.debug(|value, f| {
36                            write!(f, "[")?;
37                            for (i, item) in value.iter().enumerate() {
38                                if i > 0 {
39                                    write!(f, ", ")?;
40                                }
41                                (<VTableView<T>>::of().debug().unwrap())(
42                                    item,
43                                    f,
44                                )?;
45                            }
46                            write!(f, "]")
47                        });
48                    }
49
50                    if T::SHAPE.vtable.eq.is_some() {
51                        builder = builder.eq(|a, b|  {
52                            if a.len() != b.len() {
53                                return false;
54                            }
55                            for (item_a, item_b) in a.iter().zip(b.iter()) {
56                                if !(<VTableView<T>>::of().eq().unwrap())(
57                                    item_a,
58                                    item_b,
59                                ) {
60                                    return false;
61                                }
62                            }
63                            true
64                        });
65                    }
66
67                    if T::SHAPE.vtable.hash.is_some() {
68                        builder = builder.hash(|vec, hasher_this, hasher_write_fn| unsafe {
69                            use crate::HasherProxy;
70                            let t_hash = <VTableView<T>>::of().hash().unwrap_unchecked();
71                            let mut hasher = HasherProxy::new(hasher_this, hasher_write_fn);
72                            vec.len().hash(&mut hasher);
73                            for item in vec {
74                                (t_hash)(item, hasher_this, hasher_write_fn);
75                            }
76                        });
77                    }
78
79                    let traits = MarkerTraits::SEND
80                        .union(MarkerTraits::SYNC)
81                        .union(MarkerTraits::EQ)
82                        .union(MarkerTraits::UNPIN)
83                        .intersection(T::SHAPE.vtable.marker_traits);
84                    builder = builder.marker_traits(traits);
85
86                    builder.build()
87                },
88            )
89            .def(Def::List(
90                ListDef::builder()
91                    .vtable(
92                        &const {
93                            ListVTable::builder()
94                                .init_in_place_with_capacity(|data, capacity| unsafe {
95                                    data.put(Self::with_capacity(capacity))
96                                })
97                                .push(|ptr, item| unsafe {
98                                    let vec = ptr.as_mut::<Self>();
99                                    let item = item.read::<T>();
100                                    (*vec).push(item);
101                                })
102                                .len(|ptr| unsafe {
103                                    let vec = ptr.get::<Self>();
104                                    vec.len()
105                                })
106                                .get_item_ptr(|ptr, index| unsafe {
107                                    let vec = ptr.get::<Self>();
108                                    let len = vec.len();
109                                    if index >= len {
110                                        panic!(
111                                            "Index out of bounds: the len is {len} but the index is {index}"
112                                        );
113                                    }
114                                    PtrConst::new(vec.as_ptr().add(index))
115                                })
116                                .build()
117                        },
118                    )
119                    .t(|| T::SHAPE)
120                    .build(),
121            ))
122            .build()
123    };
124}