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