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