facet_core/_trait/impls/
vec_impl.rs1use 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}