facet_core/_trait/impls/
vec_impl.rs

1use crate::*;
2use core::{alloc::Layout, hash::Hash as _};
3
4unsafe impl<T> Facet for Vec<T>
5where
6    T: Facet,
7{
8    const SHAPE: &'static Shape = &const {
9        Shape::builder()
10            .layout(Layout::new::<Vec<T>>())
11            .vtable(
12                &const {
13                    let mut builder = ValueVTable::builder()
14                        .type_name(|f, opts| {
15                            if let Some(opts) = opts.for_children() {
16                                write!(f, "Vec<")?;
17                                (T::SHAPE.vtable.type_name)(f, opts)?;
18                                write!(f, ">")
19                            } else {
20                                write!(f, "Vec<⋯>")
21                            }
22                        })
23                        .drop_in_place(|value| unsafe {
24                            core::ptr::drop_in_place(value.as_mut::<Vec<T>>());
25                        })
26                        .default_in_place(|target| unsafe { target.write(Self::default()) })
27                        .clone_into(|src, dst| unsafe { dst.write(src.as_ref::<Vec<T>>()) });
28
29                    if T::SHAPE.vtable.debug.is_some() {
30                        builder = builder.debug(|value, f| {
31                            let value = unsafe { value.as_ref::<Vec<T>>() };
32                            write!(f, "[")?;
33                            for (i, item) in value.iter().enumerate() {
34                                if i > 0 {
35                                    write!(f, ", ")?;
36                                }
37                                unsafe {
38                                    (T::SHAPE.vtable.debug.unwrap_unchecked())(
39                                        OpaqueConst::new(item),
40                                        f,
41                                    )?;
42                                }
43                            }
44                            write!(f, "]")
45                        });
46                    }
47
48                    if T::SHAPE.vtable.eq.is_some() {
49                        builder = builder.eq(|a, b| unsafe {
50                            let a = a.as_ref::<Vec<T>>();
51                            let b = b.as_ref::<Vec<T>>();
52                            if a.len() != b.len() {
53                                return false;
54                            }
55                            for (item_a, item_b) in a.iter().zip(b.iter()) {
56                                if !(T::SHAPE.vtable.eq.unwrap_unchecked())(
57                                    OpaqueConst::new(item_a),
58                                    OpaqueConst::new(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(|value, hasher_this, hasher_write_fn| unsafe {
69                            use crate::HasherProxy;
70                            let vec = value.as_ref::<Vec<T>>();
71                            let t_hash = T::SHAPE.vtable.hash.unwrap_unchecked();
72                            let mut hasher = HasherProxy::new(hasher_this, hasher_write_fn);
73                            vec.len().hash(&mut hasher);
74                            for item in vec {
75                                (t_hash)(OpaqueConst::new(item), hasher_this, hasher_write_fn);
76                            }
77                        });
78                    }
79
80                    let mut traits = MarkerTraits::empty();
81                    if T::SHAPE.vtable.marker_traits.contains(MarkerTraits::SEND) {
82                        traits = traits.union(MarkerTraits::SEND);
83                    }
84                    if T::SHAPE.vtable.marker_traits.contains(MarkerTraits::SYNC) {
85                        traits = traits.union(MarkerTraits::SYNC);
86                    }
87                    if T::SHAPE.vtable.marker_traits.contains(MarkerTraits::EQ) {
88                        traits = traits.union(MarkerTraits::EQ);
89                    }
90                    builder = builder.marker_traits(traits);
91
92                    builder.build()
93                },
94            )
95            .def(Def::List(
96                ListDef::builder()
97                    .vtable(
98                        &const {
99                            ListVTable::builder()
100                        .init_in_place_with_capacity(|data, capacity| unsafe {
101                            Ok(data.write(Self::with_capacity(capacity)))
102                        })
103                        .push(|ptr, item| unsafe {
104                            let vec = ptr.as_mut::<Vec<T>>();
105                            let item = item.read::<T>();
106                            (*vec).push(item);
107                        })
108                        .len(|ptr| unsafe {
109                            let vec = ptr.as_ref::<Vec<T>>();
110                            vec.len()
111                        })
112                        .get_item_ptr(|ptr, index| unsafe {
113                            let vec = ptr.as_ref::<Vec<T>>();
114                            let len = vec.len();
115                            if index >= len {
116                                panic!(
117                                    "Index out of bounds: the len is {len} but the index is {index}"
118                                );
119                            }
120                            OpaqueConst::new(vec.as_ptr().add(index))
121                        })
122                        .build()
123                        },
124                    )
125                    .t(T::SHAPE)
126                    .build(),
127            ))
128            .build()
129    };
130}