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