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