1use core::{alloc::Layout, hash::Hash};
2use std::collections::{HashMap, VecDeque};
3use std::hash::RandomState;
4
5use crate::opaque::{Opaque, OpaqueConst};
6
7use crate::{
8 Def, Facet, MapDef, MapIterVTable, MapVTable, MarkerTraits, ScalarDef, Shape, ValueVTable,
9 value_vtable,
10};
11
12struct HashMapIterator<'mem, K> {
13 map: OpaqueConst<'mem>,
14 keys: VecDeque<&'mem K>,
15}
16
17unsafe impl<K, V, S> Facet for HashMap<K, V, S>
18where
19 K: Facet + core::cmp::Eq + core::hash::Hash + 'static,
20 V: Facet + 'static,
21 S: Facet + Default,
22{
23 const SHAPE: &'static Shape = &const {
24 Shape::builder()
25 .layout(Layout::new::<HashMap<K, V>>())
26 .vtable(
27 &const {
28 let mut builder = ValueVTable::builder()
29 .marker_traits({
30 let mut traits = MarkerTraits::empty();
31 if K::SHAPE.vtable.marker_traits.contains(MarkerTraits::SEND)
32 && V::SHAPE.vtable.marker_traits.contains(MarkerTraits::SEND)
33 {
34 traits = traits.union(MarkerTraits::SEND);
35 }
36 if K::SHAPE.vtable.marker_traits.contains(MarkerTraits::SYNC)
37 && V::SHAPE.vtable.marker_traits.contains(MarkerTraits::SYNC)
38 {
39 traits = traits.union(MarkerTraits::SYNC);
40 }
41 if K::SHAPE.vtable.marker_traits.contains(MarkerTraits::EQ)
42 && V::SHAPE.vtable.marker_traits.contains(MarkerTraits::EQ)
43 {
44 traits = traits.union(MarkerTraits::EQ);
45 }
46 traits
47 })
48 .type_name(|f, opts| {
49 if let Some(opts) = opts.for_children() {
50 write!(f, "HashMap<")?;
51 (K::SHAPE.vtable.type_name)(f, opts)?;
52 write!(f, ", ")?;
53 (V::SHAPE.vtable.type_name)(f, opts)?;
54 write!(f, ">")
55 } else {
56 write!(f, "HashMap<⋯>")
57 }
58 })
59 .drop_in_place(|value| unsafe {
60 core::ptr::drop_in_place(value.as_mut::<HashMap<K, V>>());
61 });
62
63 if K::SHAPE.vtable.debug.is_some() && V::SHAPE.vtable.debug.is_some() {
64 builder = builder.debug(|value, f| unsafe {
65 let value = value.as_ref::<HashMap<K, V>>();
66 let k_debug = K::SHAPE.vtable.debug.unwrap_unchecked();
67 let v_debug = V::SHAPE.vtable.debug.unwrap_unchecked();
68 write!(f, "{{")?;
69 for (i, (key, val)) in value.iter().enumerate() {
70 if i > 0 {
71 write!(f, ", ")?;
72 }
73 (k_debug)(OpaqueConst::new(key as *const _), f)?;
74 write!(f, ": ")?;
75 (v_debug)(OpaqueConst::new(val as *const _), f)?;
76 }
77 write!(f, "}}")
78 });
79 }
80
81 builder =
82 builder.default_in_place(|target| unsafe { target.write(Self::default()) });
83
84 builder = builder
85 .clone_into(|src, dst| unsafe { dst.write(src.as_ref::<HashMap<K, V>>()) });
86
87 if K::SHAPE.vtable.eq.is_some() && V::SHAPE.vtable.eq.is_some() {
88 builder = builder.eq(|a, b| unsafe {
89 let a = a.as_ref::<HashMap<K, V>>();
90 let b = b.as_ref::<HashMap<K, V>>();
91 let k_eq = K::SHAPE.vtable.eq.unwrap_unchecked();
92 let v_eq = V::SHAPE.vtable.eq.unwrap_unchecked();
93 a.len() == b.len()
94 && a.iter().all(|(key_a, val_a)| {
95 b.get(key_a).is_some_and(|val_b| {
96 (k_eq)(
97 OpaqueConst::new(key_a as *const _),
98 OpaqueConst::new(key_a as *const _),
99 ) && (v_eq)(
100 OpaqueConst::new(val_a as *const _),
101 OpaqueConst::new(val_b as *const _),
102 )
103 })
104 })
105 });
106 }
107
108 if K::SHAPE.vtable.hash.is_some() && V::SHAPE.vtable.hash.is_some() {
109 builder = builder.hash(|value, hasher_this, hasher_write_fn| unsafe {
110 use crate::HasherProxy;
111 let map = value.as_ref::<HashMap<K, V>>();
112 let k_hash = K::SHAPE.vtable.hash.unwrap_unchecked();
113 let v_hash = V::SHAPE.vtable.hash.unwrap_unchecked();
114 let mut hasher = HasherProxy::new(hasher_this, hasher_write_fn);
115 map.len().hash(&mut hasher);
116 for (k, v) in map {
117 (k_hash)(
118 OpaqueConst::new(k as *const _),
119 hasher_this,
120 hasher_write_fn,
121 );
122 (v_hash)(
123 OpaqueConst::new(v as *const _),
124 hasher_this,
125 hasher_write_fn,
126 );
127 }
128 });
129 }
130
131 builder.build()
132 },
133 )
134 .def(Def::Map(
135 MapDef::builder()
136 .k(K::SHAPE)
137 .v(V::SHAPE)
138 .vtable(
139 &const {
140 MapVTable::builder()
141 .init_in_place_with_capacity(|uninit, capacity| unsafe {
142 Ok(uninit.write(Self::with_capacity_and_hasher(
143 capacity,
144 S::default(),
145 )))
146 })
147 .insert(|ptr, key, value| unsafe {
148 let map = ptr.as_mut::<HashMap<K, V>>();
149 let key = key.read::<K>();
150 let value = value.read::<V>();
151 map.insert(key, value);
152 })
153 .len(|ptr| unsafe {
154 let map = ptr.as_ref::<HashMap<K, V>>();
155 map.len()
156 })
157 .contains_key(|ptr, key| unsafe {
158 let map = ptr.as_ref::<HashMap<K, V>>();
159 map.contains_key(key.as_ref())
160 })
161 .get_value_ptr(|ptr, key| unsafe {
162 let map = ptr.as_ref::<HashMap<K, V>>();
163 map.get(key.as_ref())
164 .map(|v| OpaqueConst::new(v as *const _))
165 })
166 .iter(|ptr| unsafe {
167 let map = ptr.as_ref::<HashMap<K, V>>();
168 let keys: VecDeque<&K> = map.keys().collect();
169 let iter_state = Box::new(HashMapIterator { map: ptr, keys });
170 Opaque::new(Box::into_raw(iter_state) as *mut u8)
171 })
172 .iter_vtable(
173 MapIterVTable::builder()
174 .next(|iter_ptr| unsafe {
175 let state = iter_ptr.as_mut::<HashMapIterator<'_, K>>();
176 let map = state.map.as_ref::<HashMap<K, V>>();
177 while let Some(key) = state.keys.pop_front() {
178 if let Some(value) = map.get(key) {
179 return Some((
180 OpaqueConst::new(key as *const K),
181 OpaqueConst::new(value as *const V),
182 ));
183 }
184 }
185
186 None
187 })
188 .dealloc(|iter_ptr| unsafe {
189 drop(Box::from_raw(
190 iter_ptr.as_ptr::<HashMapIterator<'_, K>>()
191 as *mut HashMapIterator<'_, K>,
192 ));
193 })
194 .build(),
195 )
196 .build()
197 },
198 )
199 .build(),
200 ))
201 .build()
202 };
203}
204
205#[allow(dead_code)]
206struct RandomStateInnards {
207 k0: u64,
208 k1: u64,
209}
210
211unsafe impl Facet for RandomState {
212 const SHAPE: &'static Shape = &const {
213 Shape::builder()
214 .layout(Layout::new::<Self>())
215 .def(Def::Scalar(
216 ScalarDef::builder()
217 .fully_qualified_type_name("std::collections::hash_map::RandomState")
218 .build(),
219 ))
220 .vtable(value_vtable!((), |f, _opts| write!(f, "RandomState")))
221 .build()
222 };
223}