facet_core/impls_alloc/vec.rs
1use 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 // FIXME: THIS IS VERY WRONG
32 .clone_into(|src, dst| unsafe { dst.put(core::ptr::read(src)) });
33
34 if T::SHAPE.vtable.debug.is_some() {
35 builder = builder.debug(|value, f| {
36 write!(f, "[")?;
37 for (i, item) in value.iter().enumerate() {
38 if i > 0 {
39 write!(f, ", ")?;
40 }
41 (<VTableView<T>>::of().debug().unwrap())(
42 item,
43 f,
44 )?;
45 }
46 write!(f, "]")
47 });
48 }
49
50 if T::SHAPE.vtable.eq.is_some() {
51 builder = builder.eq(|a, b| {
52 if a.len() != b.len() {
53 return false;
54 }
55 for (item_a, item_b) in a.iter().zip(b.iter()) {
56 if !(<VTableView<T>>::of().eq().unwrap())(
57 item_a,
58 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(|vec, hasher_this, hasher_write_fn| unsafe {
69 use crate::HasherProxy;
70 let t_hash = <VTableView<T>>::of().hash().unwrap_unchecked();
71 let mut hasher = HasherProxy::new(hasher_this, hasher_write_fn);
72 vec.len().hash(&mut hasher);
73 for item in vec {
74 (t_hash)(item, hasher_this, hasher_write_fn);
75 }
76 });
77 }
78
79 let traits = MarkerTraits::SEND
80 .union(MarkerTraits::SYNC)
81 .union(MarkerTraits::EQ)
82 .union(MarkerTraits::UNPIN)
83 .intersection(T::SHAPE.vtable.marker_traits);
84 builder = builder.marker_traits(traits);
85
86 builder.build()
87 },
88 )
89 .def(Def::List(
90 ListDef::builder()
91 .vtable(
92 &const {
93 ListVTable::builder()
94 .init_in_place_with_capacity(|data, capacity| unsafe {
95 data.put(Self::with_capacity(capacity))
96 })
97 .push(|ptr, item| unsafe {
98 let vec = ptr.as_mut::<Self>();
99 let item = item.read::<T>();
100 (*vec).push(item);
101 })
102 .len(|ptr| unsafe {
103 let vec = ptr.get::<Self>();
104 vec.len()
105 })
106 .get_item_ptr(|ptr, index| unsafe {
107 let vec = ptr.get::<Self>();
108 let len = vec.len();
109 if index >= len {
110 panic!(
111 "Index out of bounds: the len is {len} but the index is {index}"
112 );
113 }
114 PtrConst::new(vec.as_ptr().add(index))
115 })
116 .build()
117 },
118 )
119 .t(|| T::SHAPE)
120 .build(),
121 ))
122 .build()
123 };
124}