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