facet_trait/impls/
vec_impl.rs

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