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