facet_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 ARCHETYPE: Self = Vec::new(); const SHAPE: &'static Shape = &const {
10 Shape::builder()
11 .layout(Layout::new::<Vec<T>>())
12 .vtable(
13 &const {
14 let mut builder = ValueVTable::builder()
15 .type_name(|f, opts| {
16 if let Some(opts) = opts.for_children() {
17 write!(f, "Vec<")?;
18 (T::SHAPE.vtable.type_name)(f, opts)?;
19 write!(f, ">")
20 } else {
21 write!(f, "Vec<⋯>")
22 }
23 })
24 .drop_in_place(|value| unsafe {
25 core::ptr::drop_in_place(value.as_mut::<Vec<T>>());
26 })
27 .default_in_place(|target| unsafe { target.write(Self::default()) })
28 .clone_into(|src, dst| unsafe { dst.write(src.as_ref::<Vec<T>>()) });
29
30 if T::SHAPE.vtable.debug.is_some() {
31 builder = builder.debug(|value, f| {
32 let value = unsafe { value.as_ref::<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 OpaqueConst::from_ref(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.as_ref::<Vec<T>>();
52 let b = b.as_ref::<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 OpaqueConst::from_ref(item_a),
59 OpaqueConst::from_ref(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.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 }
80
81 let mut traits = MarkerTraits::empty();
82 if T::SHAPE.vtable.marker_traits.contains(MarkerTraits::SEND) {
83 traits = traits.union(MarkerTraits::SEND);
84 }
85 if T::SHAPE.vtable.marker_traits.contains(MarkerTraits::SYNC) {
86 traits = traits.union(MarkerTraits::SYNC);
87 }
88 if T::SHAPE.vtable.marker_traits.contains(MarkerTraits::EQ) {
89 traits = traits.union(MarkerTraits::EQ);
90 }
91 builder = builder.marker_traits(traits);
92
93 builder.build()
94 },
95 )
96 .def(Def::List(
97 ListDef::builder()
98 .vtable(
99 &const {
100 ListVTable::builder()
101 .init_in_place_with_capacity(|data, capacity| unsafe {
102 Ok(data.write(Self::with_capacity(capacity)))
103 })
104 .push(|ptr, item| unsafe {
105 let vec = ptr.as_mut::<Vec<T>>();
106 let item = item.read::<T>();
107 (*vec).push(item);
108 })
109 .len(|ptr| unsafe {
110 let vec = ptr.as_ref::<Vec<T>>();
111 vec.len()
112 })
113 .get_item_ptr(|ptr, index| unsafe {
114 let vec = ptr.as_ref::<Vec<T>>();
115 let len = vec.len();
116 if index >= len {
117 panic!(
118 "Index out of bounds: the len is {len} but the index is {index}"
119 );
120 }
121 OpaqueConst::new_unchecked(vec.as_ptr().add(index))
122 })
123 .build()
124 },
125 )
126 .t(T::SHAPE)
127 .build(),
128 ))
129 .build()
130 };
131}