1#![allow(clippy::type_repetition_in_bounds)]
4
5use core::{
6 fmt::Debug,
7 marker::PhantomData,
8 ops::{Deref, DerefMut},
9};
10
11use impl_tools::autoimpl;
12
13use crate::{Entry, Map, OccupiedEntry, VacantEntry};
14
15pub trait DefaultMap: Map<V: Default + Eq> {
17 #[inline]
34 fn entry_or_default(
35 &mut self,
36 k: Self::K,
37 ) -> DefaultEntry<'_, Self::VacantEntry<'_>, Self::OccupiedEntry<'_>> {
38 match self.entry(k) {
39 Entry::Vacant(entry) => DefaultVacantEntry::new(entry).into(),
40 Entry::Occupied(entry) => DefaultOccupiedEntry::new(entry).into(),
41 }
42 }
43}
44impl<T> DefaultMap for T where T: Map<V: Default + Eq> {}
45
46#[autoimpl(Debug where V: Debug, V::V: Debug, O: Debug)]
47pub enum DefaultEntry<'a, V, O>
48where
49 V: VacantEntry<'a, V: Default + Eq>,
50 O: OccupiedEntry<'a, K = V::K, V = V::V>,
51{
52 Vacant(DefaultVacantEntry<'a, V>),
53 Occupied(DefaultOccupiedEntry<'a, O>),
54}
55
56impl<'a, V, O> DefaultEntry<'a, V, O>
57where
58 V: VacantEntry<'a, V: Default + Eq>,
59 O: OccupiedEntry<'a, K = V::K, V = V::V>,
60{
61 #[inline]
72 pub fn key(&self) -> &V::K {
73 match self {
74 Self::Vacant(entry) => entry.key(),
75 Self::Occupied(entry) => entry.key(),
76 }
77 }
78
79 #[inline]
93 pub fn remove(self) -> V::V {
94 match self {
95 Self::Vacant(entry) => entry.remove(),
96 Self::Occupied(entry) => entry.remove(),
97 }
98 }
99}
100
101impl<'a, V, O> Deref for DefaultEntry<'a, V, O>
102where
103 V: VacantEntry<'a, V: Default + Eq>,
104 O: OccupiedEntry<'a, K = V::K, V = V::V>,
105{
106 type Target = V::V;
107
108 #[inline]
109 fn deref(&self) -> &Self::Target {
110 match self {
111 Self::Vacant(entry) => entry,
112 Self::Occupied(entry) => entry,
113 }
114 }
115}
116
117impl<'a, V, O> DerefMut for DefaultEntry<'a, V, O>
118where
119 V: VacantEntry<'a, V: Default + Eq>,
120 O: OccupiedEntry<'a, K = V::K, V = V::V>,
121{
122 #[inline]
123 fn deref_mut(&mut self) -> &mut Self::Target {
124 match self {
125 Self::Vacant(entry) => entry,
126 Self::Occupied(entry) => entry,
127 }
128 }
129}
130
131impl<'a, V, O> From<DefaultVacantEntry<'a, V>> for DefaultEntry<'a, V, O>
132where
133 V: VacantEntry<'a, V: Default + Eq>,
134 O: OccupiedEntry<'a, K = V::K, V = V::V>,
135{
136 #[inline]
137 fn from(entry: DefaultVacantEntry<'a, V>) -> Self {
138 Self::Vacant(entry)
139 }
140}
141
142impl<'a, V, O> From<DefaultOccupiedEntry<'a, O>> for DefaultEntry<'a, V, O>
143where
144 V: VacantEntry<'a, V: Default + Eq>,
145 O: OccupiedEntry<'a, K = V::K, V = V::V>,
146{
147 #[inline]
148 fn from(entry: DefaultOccupiedEntry<'a, O>) -> Self {
149 Self::Occupied(entry)
150 }
151}
152
153#[derive(Debug)]
154pub struct DefaultVacantEntry<'a, E: 'a>(Option<(E::V, E)>)
155where
156 E: VacantEntry<'a, V: Default + Eq>;
157
158impl<'a, E: 'a> DefaultVacantEntry<'a, E>
159where
160 E: VacantEntry<'a, V: Default + Eq>,
161{
162 #[inline]
163 pub fn new(entry: E) -> Self {
164 Self(Some((Default::default(), entry)))
165 }
166
167 #[inline]
168 pub fn key(&self) -> &E::K {
169 self.0.as_ref().unwrap_or_else(|| unreachable!()).1.key()
170 }
171
172 #[inline]
173 pub fn remove(mut self) -> E::V {
174 self.0.take().unwrap_or_else(|| unreachable!()).0
175 }
176}
177
178impl<'a, E: 'a> Deref for DefaultVacantEntry<'a, E>
179where
180 E: VacantEntry<'a, V: Default + Eq>,
181{
182 type Target = E::V;
183
184 #[inline]
185 fn deref(&self) -> &Self::Target {
186 &self.0.as_ref().unwrap_or_else(|| unreachable!()).0
187 }
188}
189
190impl<'a, E: 'a> DerefMut for DefaultVacantEntry<'a, E>
191where
192 E: VacantEntry<'a, V: Default + Eq>,
193{
194 #[inline]
195 fn deref_mut(&mut self) -> &mut Self::Target {
196 &mut self.0.as_mut().unwrap_or_else(|| unreachable!()).0
197 }
198}
199
200impl<'a, E: 'a> Drop for DefaultVacantEntry<'a, E>
201where
202 E: VacantEntry<'a, V: Default + Eq>,
203{
204 #[inline]
205 fn drop(&mut self) {
206 let Some((v, entry)) = self.0.take() else {
207 return;
208 };
209 if v != Default::default() {
210 entry.insert(v);
211 }
212 }
213}
214
215#[derive(Debug)]
216pub struct DefaultOccupiedEntry<'a, E>(Option<E>, PhantomData<&'a ()>)
217where
218 E: OccupiedEntry<'a, V: Default + Eq>;
219
220impl<'a, E> DefaultOccupiedEntry<'a, E>
221where
222 E: OccupiedEntry<'a, V: Default + Eq>,
223{
224 #[inline]
225 pub const fn new(entry: E) -> Self {
226 Self(Some(entry), PhantomData)
227 }
228
229 #[inline]
230 pub fn key(&self) -> &E::K {
231 self.0.as_ref().unwrap_or_else(|| unreachable!()).key()
232 }
233
234 #[inline]
235 pub fn remove(mut self) -> E::V {
236 self.0.take().unwrap_or_else(|| unreachable!()).remove()
237 }
238}
239
240impl<'a, E> Deref for DefaultOccupiedEntry<'a, E>
241where
242 E: OccupiedEntry<'a, V: Default + Eq>,
243{
244 type Target = E::V;
245
246 #[inline]
247 fn deref(&self) -> &Self::Target {
248 self.0.as_ref().unwrap_or_else(|| unreachable!()).get()
249 }
250}
251
252impl<'a, E> DerefMut for DefaultOccupiedEntry<'a, E>
253where
254 E: OccupiedEntry<'a, V: Default + Eq>,
255{
256 #[inline]
257 fn deref_mut(&mut self) -> &mut Self::Target {
258 self.0.as_mut().unwrap_or_else(|| unreachable!()).get_mut()
259 }
260}
261
262impl<'a, E> Drop for DefaultOccupiedEntry<'a, E>
263where
264 E: OccupiedEntry<'a, V: Default + Eq>,
265{
266 #[inline]
267 fn drop(&mut self) {
268 let Some(entry) = self.0.take() else {
269 return;
270 };
271 if entry.get() == &Default::default() {
272 entry.remove();
273 }
274 }
275}