1use super::Removed;
2use core::{mem::forget, ptr::NonNull};
3use owned_alloc::{OwnedAlloc, UninitAlloc};
4
5#[derive(Debug, PartialEq, Eq)]
7pub enum Insertion<K, V, E> {
8 Created,
10 Updated(Removed<K, V>),
12 Failed(E),
17}
18
19impl<K, V, E> Insertion<K, V, E> {
20 pub fn created(&self) -> bool {
22 matches!(self, Insertion::Created)
23 }
24
25 pub fn updated(&self) -> Option<&Removed<K, V>> {
27 match self {
28 Insertion::Updated(pair) => Some(pair),
29 _ => None,
30 }
31 }
32
33 pub fn take_updated(self) -> Result<Removed<K, V>, Self> {
36 match self {
37 Insertion::Updated(pair) => Ok(pair),
38 this => Err(this),
39 }
40 }
41
42 pub fn failed(&self) -> Option<&E> {
44 match self {
45 Insertion::Failed(err) => Some(err),
46 _ => None,
47 }
48 }
49
50 pub fn take_failed(self) -> Result<E, Self> {
53 match self {
54 Insertion::Failed(e) => Ok(e),
55 this => Err(this),
56 }
57 }
58}
59
60#[derive(Debug, Clone, Copy, PartialEq, Eq)]
64pub enum Preview<V> {
65 Discard,
70 Keep,
74 New(V),
77}
78
79pub trait Inserter<K, V>: Sized {
82 fn input(&mut self, found: Option<&(K, V)>);
84
85 fn pointer(&self) -> Option<NonNull<(K, V)>>;
88
89 fn key(&self) -> &K;
91
92 fn take_pointer(self) {
94 forget(self);
95 }
96}
97
98pub struct InsertNew<F, K, V>
100where
101 F: FnMut(&K, Option<&mut V>, Option<&(K, V)>) -> Preview<V>,
102{
103 interactive: F,
104 nnptr: NonNull<(K, V)>,
105 is_val_init: bool,
106}
107
108impl<F, K, V> InsertNew<F, K, V>
109where
110 F: FnMut(&K, Option<&mut V>, Option<&(K, V)>) -> Preview<V>,
111{
112 pub fn with_key(interactive: F, key: K) -> Self {
113 Self {
114 interactive,
115 nnptr: unsafe {
118 let alloc =
119 UninitAlloc::new().init_in_place(|(key_mem, _)| (key_mem as *mut K).write(key));
120 alloc.into_raw()
121 },
122 is_val_init: false,
123 }
124 }
125
126 pub fn with_pair(interactive: F, pair: (K, V)) -> Self {
127 Self {
128 interactive,
129 nnptr: OwnedAlloc::new(pair).forget_inner().into_raw(),
130 is_val_init: true,
131 }
132 }
133
134 pub fn into_pair(self) -> (K, Option<V>) {
135 let ((key, val), _) = unsafe { OwnedAlloc::from_raw(self.nnptr) }.move_inner();
138 let val = if self.is_val_init {
140 Some(val)
141 } else {
142 forget(val);
143 None
144 };
145 forget(self);
146 (key, val)
147 }
148}
149
150impl<F, K, V> Drop for InsertNew<F, K, V>
151where
152 F: FnMut(&K, Option<&mut V>, Option<&(K, V)>) -> Preview<V>,
153{
154 fn drop(&mut self) {
155 if self.is_val_init {
158 unsafe { OwnedAlloc::from_raw(self.nnptr) };
159 } else {
160 unsafe {
161 {
162 let (key, _) = self.nnptr.as_mut();
163 (key as *mut K).drop_in_place();
164 }
165 UninitAlloc::from_raw(self.nnptr);
166 }
167 }
168 }
169}
170
171impl<F, K, V> Inserter<K, V> for InsertNew<F, K, V>
172where
173 F: FnMut(&K, Option<&mut V>, Option<&(K, V)>) -> Preview<V>,
174{
175 fn input(&mut self, found: Option<&(K, V)>) {
176 let (key, val) = unsafe { self.nnptr.as_mut() };
178
179 let preview = {
180 let val = if self.is_val_init {
181 Some(&mut *val)
182 } else {
183 None
184 };
185 (self.interactive)(key, val, found)
186 };
187
188 match preview {
189 Preview::Discard if self.is_val_init => {
190 self.is_val_init = false;
191 unsafe { (val as *mut V).drop_in_place() };
194 }
195
196 Preview::New(new_val) => {
197 if self.is_val_init {
198 *val = new_val;
199 } else {
200 self.is_val_init = true;
201 unsafe { (val as *mut V).write(new_val) };
204 }
205 }
206
207 _ => (),
208 }
209 }
210
211 fn pointer(&self) -> Option<NonNull<(K, V)>> {
212 if self.is_val_init {
213 Some(self.nnptr)
214 } else {
215 None
216 }
217 }
218
219 fn key(&self) -> &K {
220 let (key, _) = unsafe { self.nnptr.as_ref() };
222 key
223 }
224}
225
226pub struct Reinsert<F, K, V>
228where
229 F: FnMut(&(K, V), Option<&(K, V)>) -> bool,
230{
231 interactive: F,
232 removed: Removed<K, V>,
233 is_valid: bool,
234}
235
236impl<F, K, V> Reinsert<F, K, V>
237where
238 F: FnMut(&(K, V), Option<&(K, V)>) -> bool,
239{
240 pub fn new(interactive: F, removed: Removed<K, V>) -> Self {
241 Self {
242 interactive,
243 removed,
244 is_valid: false,
245 }
246 }
247
248 pub fn into_removed(self) -> Removed<K, V> {
249 self.removed
250 }
251}
252
253impl<F, K, V> Inserter<K, V> for Reinsert<F, K, V>
254where
255 F: FnMut(&(K, V), Option<&(K, V)>) -> bool,
256{
257 fn input(&mut self, found: Option<&(K, V)>) {
258 self.is_valid = (self.interactive)(&self.removed, found);
259 }
260
261 fn pointer(&self) -> Option<NonNull<(K, V)>> {
262 if self.is_valid {
263 Some(Removed::raw(&self.removed))
264 } else {
265 None
266 }
267 }
268
269 fn key(&self) -> &K {
270 let (key, _) = &*self.removed;
271 key
272 }
273
274 fn take_pointer(self) {
275 forget(Removed::into_alloc(self.removed));
276 }
277}