1use std::any::Any;
52use std::marker::PhantomData;
53use std::sync::OnceLock;
54
55use crate::context;
56
57#[allow(dead_code)]
58mod weak_map {
59 use std::collections::HashMap;
65 use std::sync::Arc;
66 use std::sync::Mutex;
67 use std::sync::MutexGuard;
68 use std::sync::Weak;
69
70 trait ErasedWeakMap: Send + Sync {
72 fn remove_by_ptr(&self, ptr: *const WeakKeyInner);
74 }
75
76 #[derive(Clone, Copy)]
80 struct MapPtr(*const dyn ErasedWeakMap);
81
82 impl MapPtr {
83 fn data_ptr(&self) -> *const () {
85 self.0 as *const ()
86 }
87 }
88
89 impl PartialEq for MapPtr {
90 fn eq(&self, other: &Self) -> bool {
91 self.data_ptr() == other.data_ptr()
92 }
93 }
94
95 impl Eq for MapPtr {}
96
97 impl std::hash::Hash for MapPtr {
98 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
99 self.data_ptr().hash(state);
100 }
101 }
102
103 unsafe impl Send for MapPtr {}
106 unsafe impl Sync for MapPtr {}
109
110 struct WeakKeyInner {
112 maps: Mutex<HashMap<MapPtr, Weak<dyn ErasedWeakMap>>>,
115 }
116
117 impl WeakKeyInner {
118 fn unregister_map(&self, map_ptr: *const dyn ErasedWeakMap) {
119 let mut maps = self.maps.lock().unwrap();
120 maps.remove(&MapPtr(map_ptr));
121 }
122 }
123
124 impl Drop for WeakKeyInner {
125 fn drop(&mut self) {
131 let maps = self.maps.lock().unwrap();
132 let self_ptr = self as *const WeakKeyInner;
133 for weak_map in maps.values() {
134 if let Some(map) = weak_map.upgrade() {
135 map.remove_by_ptr(self_ptr);
136 }
137 }
138 }
139 }
140
141 #[derive(Clone)]
143 pub struct WeakKey {
144 inner: Arc<WeakKeyInner>,
145 }
146
147 impl WeakKey {
148 pub fn new() -> Self {
149 Self {
150 inner: Arc::new(WeakKeyInner {
151 maps: Mutex::new(HashMap::new()),
152 }),
153 }
154 }
155
156 fn as_ptr(&self) -> *const WeakKeyInner {
157 Arc::as_ptr(&self.inner)
158 }
159
160 fn downgrade(&self) -> Weak<WeakKeyInner> {
161 Arc::downgrade(&self.inner)
162 }
163
164 fn register_map(&self, map: Weak<dyn ErasedWeakMap>) {
165 let mut maps = self.inner.maps.lock().unwrap();
166 maps.insert(MapPtr(map.as_ptr()), map);
167 }
168
169 fn unregister_map(&self, map_ptr: *const dyn ErasedWeakMap) {
170 self.inner.unregister_map(map_ptr);
171 }
172
173 #[cfg(test)]
174 pub fn maps_len(&self) -> usize {
175 self.inner.maps.lock().unwrap().len()
176 }
177 }
178
179 struct WeakMapInner<T: Send + 'static> {
181 entries: Mutex<HashMap<*const WeakKeyInner, (Weak<WeakKeyInner>, T)>>,
182 }
183
184 unsafe impl<T: Send + 'static> Send for WeakMapInner<T> {}
187 unsafe impl<T: Send + 'static> Sync for WeakMapInner<T> {}
190
191 impl<T: Send + 'static> ErasedWeakMap for WeakMapInner<T> {
192 fn remove_by_ptr(&self, ptr: *const WeakKeyInner) {
193 let mut entries = self.entries.lock().unwrap();
194 entries.remove(&ptr);
195 }
196 }
197
198 impl<T: Send + 'static> Drop for WeakMapInner<T> {
199 fn drop(&mut self) {
203 let entries = self.entries.lock().unwrap();
204 let self_ptr = self as *const WeakMapInner<T> as *const dyn ErasedWeakMap;
205 for (_, (weak_key, _)) in entries.iter() {
206 if let Some(key_inner) = weak_key.upgrade() {
207 key_inner.unregister_map(self_ptr);
208 }
209 }
210 }
211 }
212
213 fn as_erased<T: Send + 'static>(inner: &Arc<WeakMapInner<T>>) -> Weak<dyn ErasedWeakMap> {
214 Arc::downgrade(inner) as Weak<dyn ErasedWeakMap>
215 }
216
217 pub struct WeakMap<T: Send + 'static> {
219 inner: Arc<WeakMapInner<T>>,
220 }
221
222 impl<T: Send + 'static> WeakMap<T> {
223 pub fn new() -> Self {
224 Self {
225 inner: Arc::new(WeakMapInner {
226 entries: Mutex::new(HashMap::new()),
227 }),
228 }
229 }
230
231 pub fn entry<'a>(&'a self, key: &'a WeakKey) -> Entry<'a, T> {
233 let key_ptr = key.as_ptr();
234 let guard = self.inner.entries.lock().unwrap();
235
236 if guard.contains_key(&key_ptr) {
237 Entry::Occupied(OccupiedEntry {
238 guard,
239 key_ptr,
240 key,
241 map_inner: &self.inner,
242 })
243 } else {
244 Entry::Vacant(VacantEntry {
245 guard,
246 key_ptr,
247 key,
248 map_inner: &self.inner,
249 })
250 }
251 }
252
253 #[cfg(test)]
254 fn contains_key(&self, key: &WeakKey) -> bool {
255 let guard = self.inner.entries.lock().unwrap();
256 guard.contains_key(&key.as_ptr())
257 }
258
259 #[cfg(test)]
260 fn get(&self, key: &WeakKey) -> Option<T>
261 where
262 T: Clone,
263 {
264 let guard = self.inner.entries.lock().unwrap();
265 guard.get(&key.as_ptr()).map(|(_, v)| v.clone())
266 }
267
268 #[cfg(test)]
269 fn len(&self) -> usize {
270 let guard = self.inner.entries.lock().unwrap();
271 guard.len()
272 }
273 }
274
275 pub enum Entry<'a, T: Send + 'static> {
279 Occupied(OccupiedEntry<'a, T>),
281 Vacant(VacantEntry<'a, T>),
283 }
284
285 pub struct OccupiedEntry<'a, T: Send + 'static> {
289 guard: MutexGuard<'a, HashMap<*const WeakKeyInner, (Weak<WeakKeyInner>, T)>>,
290 key_ptr: *const WeakKeyInner,
291 key: &'a WeakKey,
292 map_inner: &'a Arc<WeakMapInner<T>>,
293 }
294
295 pub struct VacantEntry<'a, T: Send + 'static> {
299 guard: MutexGuard<'a, HashMap<*const WeakKeyInner, (Weak<WeakKeyInner>, T)>>,
300 key_ptr: *const WeakKeyInner,
301 key: &'a WeakKey,
302 map_inner: &'a Arc<WeakMapInner<T>>,
303 }
304
305 impl<'a, T: Send + 'static> Entry<'a, T> {
306 pub fn or_insert(self, default: T) -> OccupiedEntry<'a, T> {
309 match self {
310 Entry::Occupied(o) => o,
311 Entry::Vacant(v) => v.insert(default),
312 }
313 }
314
315 pub fn or_insert_with<F: FnOnce() -> T>(self, f: F) -> OccupiedEntry<'a, T> {
318 match self {
319 Entry::Occupied(o) => o,
320 Entry::Vacant(v) => v.insert(f()),
321 }
322 }
323
324 pub fn and_modify<F: FnOnce(&mut T)>(mut self, f: F) -> Self {
327 if let Entry::Occupied(ref mut o) = self {
328 f(o.get_mut());
329 }
330 self
331 }
332 }
333
334 impl<'a, T: Send + Default + 'static> Entry<'a, T> {
335 pub fn or_default(self) -> OccupiedEntry<'a, T> {
338 self.or_insert_with(T::default)
339 }
340 }
341
342 impl<'a, T: Send + 'static> OccupiedEntry<'a, T> {
343 pub fn get(&self) -> &T {
345 &self
346 .guard
347 .get(&self.key_ptr)
348 .expect("OccupiedEntry should have value")
349 .1
350 }
351
352 pub fn get_mut(&mut self) -> &mut T {
354 &mut self
355 .guard
356 .get_mut(&self.key_ptr)
357 .expect("OccupiedEntry should have value")
358 .1
359 }
360
361 pub fn insert(&mut self, value: T) -> T {
364 let entry = self
365 .guard
366 .get_mut(&self.key_ptr)
367 .expect("OccupiedEntry should have value");
368 std::mem::replace(&mut entry.1, value)
369 }
370
371 pub fn remove(mut self) -> T {
373 let (_, value) = self
374 .guard
375 .remove(&self.key_ptr)
376 .expect("OccupiedEntry should have value");
377
378 let map_ptr = Arc::as_ptr(self.map_inner) as *const dyn ErasedWeakMap;
380 self.key.unregister_map(map_ptr);
381
382 value
383 }
384 }
385
386 impl<'a, T: Send + 'static> VacantEntry<'a, T> {
387 pub fn insert(mut self, value: T) -> OccupiedEntry<'a, T> {
390 self.key.register_map(as_erased(self.map_inner));
392
393 self.guard
394 .insert(self.key_ptr, (self.key.downgrade(), value));
395
396 OccupiedEntry {
397 guard: self.guard,
398 key_ptr: self.key_ptr,
399 key: self.key,
400 map_inner: self.map_inner,
401 }
402 }
403 }
404
405 #[cfg(test)]
406 mod tests {
407 use super::*;
408
409 #[test]
410 fn test_weak_key_creation() {
411 let key1 = WeakKey::new();
412 let key2 = WeakKey::new();
413
414 assert_ne!(key1.as_ptr(), key2.as_ptr());
416 }
417
418 #[test]
419 fn test_weak_map_basic_operations() {
420 let map: WeakMap<u64> = WeakMap::new();
421 let key = WeakKey::new();
422
423 assert!(!map.contains_key(&key));
425
426 match map.entry(&key) {
428 Entry::Vacant(v) => {
429 v.insert(42);
430 }
431 Entry::Occupied(_) => panic!("expected vacant"),
432 }
433
434 assert!(map.contains_key(&key));
436 assert_eq!(map.get(&key), Some(42));
437
438 match map.entry(&key) {
440 Entry::Occupied(mut o) => {
441 *o.get_mut() = 100;
442 }
443 Entry::Vacant(_) => panic!("expected occupied"),
444 }
445
446 assert_eq!(map.get(&key), Some(100));
448
449 match map.entry(&key) {
451 Entry::Occupied(o) => {
452 let removed = o.remove();
453 assert_eq!(removed, 100);
454 }
455 Entry::Vacant(_) => panic!("expected occupied"),
456 }
457
458 assert!(!map.contains_key(&key));
460 }
461
462 #[test]
463 fn test_key_drop_clears_map_entries() {
464 let map: WeakMap<String> = WeakMap::new();
465
466 {
467 let key = WeakKey::new();
468
469 map.entry(&key).or_insert("hello".to_string());
471
472 assert!(map.contains_key(&key));
474 assert_eq!(map.len(), 1);
475
476 }
478
479 assert_eq!(map.len(), 0);
481 }
482
483 #[test]
484 fn test_key_drop_clears_map_entries_with_scoped_key() {
485 let map: WeakMap<String> = WeakMap::new();
486
487 let weak_ref = {
488 let key = WeakKey::new();
489
490 map.entry(&key).or_insert("hello".to_string());
492
493 assert!(map.contains_key(&key));
495
496 key.downgrade()
498 };
500
501 assert!(weak_ref.upgrade().is_none());
503 }
504
505 #[test]
506 fn test_multiple_maps_same_key() {
507 let map1: WeakMap<u64> = WeakMap::new();
508 let map2: WeakMap<String> = WeakMap::new();
509
510 {
511 let key = WeakKey::new();
512
513 map1.entry(&key).or_insert(42);
515 map2.entry(&key).or_insert("test".to_string());
516
517 assert!(map1.contains_key(&key));
519 assert!(map2.contains_key(&key));
520 assert_eq!(map1.len(), 1);
521 assert_eq!(map2.len(), 1);
522
523 }
525
526 assert_eq!(map1.len(), 0);
528 assert_eq!(map2.len(), 0);
529 }
530
531 #[test]
532 fn test_no_duplicate_map_registration() {
533 let map: WeakMap<u64> = WeakMap::new();
534 let key = WeakKey::new();
535
536 map.entry(&key).or_insert(1);
538 *map.entry(&key).or_insert(2).get_mut() = 3;
540
541 assert_eq!(key.maps_len(), 1);
543 }
544
545 #[test]
546 fn test_unregister_map_on_remove() {
547 let map: WeakMap<u64> = WeakMap::new();
548 let key = WeakKey::new();
549
550 map.entry(&key).or_insert(42);
552 assert_eq!(key.maps_len(), 1);
553
554 if let Entry::Occupied(o) = map.entry(&key) {
556 o.remove();
557 }
558
559 assert_eq!(key.maps_len(), 0);
561 }
562
563 #[test]
564 fn test_concurrent_access_different_maps() {
565 let map1: WeakMap<u64> = WeakMap::new();
566 let map2: WeakMap<u64> = WeakMap::new();
567 let key = WeakKey::new();
568
569 map1.entry(&key).or_insert(1);
571 map2.entry(&key).or_insert(2);
572
573 assert_eq!(map1.get(&key), Some(1));
575 assert_eq!(map2.get(&key), Some(2));
576 }
577
578 #[test]
579 fn test_entry_or_default() {
580 let map: WeakMap<u64> = WeakMap::new();
581 let key = WeakKey::new();
582
583 *map.entry(&key).or_default().get_mut() = 42;
585 assert_eq!(map.get(&key), Some(42));
586 }
587
588 #[test]
589 fn test_entry_and_modify() {
590 let map: WeakMap<u64> = WeakMap::new();
591 let key = WeakKey::new();
592
593 map.entry(&key).and_modify(|v| *v += 10).or_insert(5);
595 assert_eq!(map.get(&key), Some(5));
596
597 map.entry(&key).and_modify(|v| *v += 10).or_insert(0);
599 assert_eq!(map.get(&key), Some(15));
600 }
601
602 #[test]
603 fn test_map_drop_unregisters_from_keys() {
604 let key = WeakKey::new();
605
606 {
607 let map: WeakMap<u64> = WeakMap::new();
608 map.entry(&key).or_insert(42);
609
610 assert_eq!(key.maps_len(), 1);
612
613 }
615
616 assert_eq!(key.maps_len(), 0);
618 }
619
620 #[test]
621 fn test_multiple_maps_drop_unregisters_all() {
622 let key = WeakKey::new();
623
624 {
625 let map1: WeakMap<u64> = WeakMap::new();
626 let map2: WeakMap<String> = WeakMap::new();
627
628 map1.entry(&key).or_insert(42);
629 map2.entry(&key).or_insert("test".to_string());
630
631 assert_eq!(key.maps_len(), 2);
633
634 drop(map1);
636 assert_eq!(key.maps_len(), 1);
637
638 }
640
641 assert_eq!(key.maps_len(), 0);
643 }
644 }
645}
646
647use weak_map::WeakKey;
648use weak_map::WeakMap;
649
650type ErasedValue = Box<dyn Any + Send>;
652
653pub struct ActorLocalStorage {
659 map: WeakMap<ErasedValue>,
660}
661
662impl Default for ActorLocalStorage {
663 fn default() -> Self {
664 Self::new()
665 }
666}
667
668impl ActorLocalStorage {
669 pub fn new() -> Self {
671 Self {
672 map: WeakMap::new(),
673 }
674 }
675
676 fn map(&self) -> &WeakMap<ErasedValue> {
678 &self.map
679 }
680}
681
682pub struct ActorLocal<T: Send + 'static> {
714 key: OnceLock<WeakKey>,
715 _marker: PhantomData<fn() -> T>,
716}
717
718unsafe impl<T: Send + 'static> Send for ActorLocal<T> {}
720unsafe impl<T: Send + 'static> Sync for ActorLocal<T> {}
722
723impl<T: Send + 'static> ActorLocal<T> {
724 pub const fn new() -> Self {
726 Self {
727 key: OnceLock::new(),
728 _marker: PhantomData,
729 }
730 }
731
732 fn key(&self) -> &WeakKey {
734 self.key.get_or_init(WeakKey::new)
735 }
736
737 pub fn entry<'a, Cx: context::Actor>(&'a self, cx: &'a Cx) -> Entry<'a, T> {
742 let map = cx.instance().locals().map();
743 let key = self.key();
744 Entry::new(map.entry(key))
745 }
746}
747
748impl<T: Send + 'static> Default for ActorLocal<T> {
749 fn default() -> Self {
750 Self::new()
751 }
752}
753
754impl<T: Send + 'static> Clone for ActorLocal<T> {
755 fn clone(&self) -> Self {
756 Self {
757 key: self.key.clone(),
758 _marker: PhantomData,
759 }
760 }
761}
762
763pub enum Entry<'a, T: Send + 'static> {
768 Occupied(OccupiedEntry<'a, T>),
770 Vacant(VacantEntry<'a, T>),
772}
773
774impl<'a, T: Send + 'static> Entry<'a, T> {
775 fn new(entry: weak_map::Entry<'a, ErasedValue>) -> Self {
776 match entry {
777 weak_map::Entry::Occupied(o) => Entry::Occupied(OccupiedEntry(o, PhantomData)),
778 weak_map::Entry::Vacant(v) => Entry::Vacant(VacantEntry(v, PhantomData)),
779 }
780 }
781
782 pub fn or_insert(self, default: T) -> OccupiedEntry<'a, T> {
785 match self {
786 Entry::Occupied(o) => o,
787 Entry::Vacant(v) => v.insert(default),
788 }
789 }
790
791 pub fn or_insert_with<F: FnOnce() -> T>(self, f: F) -> OccupiedEntry<'a, T> {
794 match self {
795 Entry::Occupied(o) => o,
796 Entry::Vacant(v) => v.insert(f()),
797 }
798 }
799
800 pub fn and_modify<F: FnOnce(&mut T)>(mut self, f: F) -> Self {
803 if let Entry::Occupied(ref mut o) = self {
804 f(o.get_mut());
805 }
806 self
807 }
808}
809
810impl<'a, T: Send + Default + 'static> Entry<'a, T> {
811 pub fn or_default(self) -> OccupiedEntry<'a, T> {
814 self.or_insert_with(T::default)
815 }
816}
817
818pub struct OccupiedEntry<'a, T: Send + 'static>(
820 weak_map::OccupiedEntry<'a, ErasedValue>,
821 PhantomData<fn() -> T>,
822);
823
824impl<'a, T: Send + 'static> OccupiedEntry<'a, T> {
825 pub fn get(&self) -> &T {
827 self.0
828 .get()
829 .downcast_ref::<T>()
830 .expect("type mismatch in actor-local storage")
831 }
832
833 pub fn get_mut(&mut self) -> &mut T {
835 self.0
836 .get_mut()
837 .downcast_mut::<T>()
838 .expect("type mismatch in actor-local storage")
839 }
840
841 pub fn insert(&mut self, value: T) -> T {
843 let old = self.0.insert(Box::new(value));
844 *old.downcast::<T>()
845 .expect("type mismatch in actor-local storage")
846 }
847
848 pub fn remove(self) -> T {
850 let value = self.0.remove();
851 *value
852 .downcast::<T>()
853 .expect("type mismatch in actor-local storage")
854 }
855}
856
857pub struct VacantEntry<'a, T: Send + 'static>(
859 weak_map::VacantEntry<'a, ErasedValue>,
860 PhantomData<fn() -> T>,
861);
862
863impl<'a, T: Send + 'static> VacantEntry<'a, T> {
864 pub fn insert(self, value: T) -> OccupiedEntry<'a, T> {
866 OccupiedEntry(self.0.insert(Box::new(value)), PhantomData)
867 }
868}
869
870#[cfg(test)]
871mod tests {
872 use super::*;
873
874 #[test]
875 fn test_actor_local_storage_creation() {
876 let storage = ActorLocalStorage::new();
877 drop(storage);
879 }
880
881 #[test]
882 fn test_storage_drop_clears_all_actor_locals() {
883 let local1: ActorLocal<u64> = ActorLocal::new();
884 let local2: ActorLocal<String> = ActorLocal::new();
885
886 {
887 let storage = ActorLocalStorage::new();
888 let map = storage.map();
889
890 map.entry(local1.key()).or_insert(Box::new(42u64));
892 map.entry(local2.key())
893 .or_insert(Box::new("test".to_string()));
894
895 assert!(matches!(
897 map.entry(local1.key()),
898 weak_map::Entry::Occupied(_)
899 ));
900 assert!(matches!(
901 map.entry(local2.key()),
902 weak_map::Entry::Occupied(_)
903 ));
904 assert_eq!(local1.key().maps_len(), 1);
905 assert_eq!(local2.key().maps_len(), 1);
906
907 }
909
910 assert_eq!(local1.key().maps_len(), 0);
912 assert_eq!(local2.key().maps_len(), 0);
913 }
914
915 #[test]
916 fn test_multiple_storages_same_local() {
917 let local: ActorLocal<u64> = ActorLocal::new();
918
919 let storage1 = ActorLocalStorage::new();
920 let storage2 = ActorLocalStorage::new();
921
922 let map1 = storage1.map();
923 let map2 = storage2.map();
924 let key = local.key();
925
926 map1.entry(key).or_insert(Box::new(100u64));
928 map2.entry(key).or_insert(Box::new(200u64));
929
930 assert_eq!(
932 *map1
933 .entry(key)
934 .or_insert(Box::new(0u64))
935 .get()
936 .downcast_ref::<u64>()
937 .unwrap(),
938 100
939 );
940 assert_eq!(
941 *map2
942 .entry(key)
943 .or_insert(Box::new(0u64))
944 .get()
945 .downcast_ref::<u64>()
946 .unwrap(),
947 200
948 );
949
950 drop(storage1);
952
953 assert_eq!(
955 *map2
956 .entry(key)
957 .or_insert(Box::new(0u64))
958 .get()
959 .downcast_ref::<u64>()
960 .unwrap(),
961 200
962 );
963 }
964
965 #[test]
966 fn test_concurrent_access_different_locals() {
967 static LOCAL1: ActorLocal<u64> = ActorLocal::new();
968 static LOCAL2: ActorLocal<u64> = ActorLocal::new();
969
970 let storage = ActorLocalStorage::new();
971 let map = storage.map();
972
973 map.entry(LOCAL1.key()).or_insert(Box::new(1u64));
975 map.entry(LOCAL2.key()).or_insert(Box::new(2u64));
976
977 assert_eq!(
979 *map.entry(LOCAL1.key())
980 .or_insert(Box::new(0u64))
981 .get()
982 .downcast_ref::<u64>()
983 .unwrap(),
984 1
985 );
986 assert_eq!(
987 *map.entry(LOCAL2.key())
988 .or_insert(Box::new(0u64))
989 .get()
990 .downcast_ref::<u64>()
991 .unwrap(),
992 2
993 );
994 }
995
996 #[test]
997 fn test_actor_local_clone_shares_key() {
998 let local1: ActorLocal<u64> = ActorLocal::new();
999 let _ = local1.key();
1001 let local2 = local1.clone();
1002
1003 let storage = ActorLocalStorage::new();
1004 let map = storage.map();
1005
1006 map.entry(local1.key()).or_insert(Box::new(42u64));
1008
1009 assert_eq!(
1011 *map.entry(local2.key())
1012 .or_insert(Box::new(0u64))
1013 .get()
1014 .downcast_ref::<u64>()
1015 .unwrap(),
1016 42
1017 );
1018 }
1019
1020 #[test]
1021 fn test_entry_fluent_api() {
1022 let local: ActorLocal<u64> = ActorLocal::new();
1023 let storage = ActorLocalStorage::new();
1024 let map = storage.map();
1025 let key = local.key();
1026
1027 let entry = Entry::<u64>::new(map.entry(key));
1029 *entry.or_default().get_mut() = 42;
1030
1031 let entry = Entry::<u64>::new(map.entry(key));
1032 assert_eq!(*entry.or_default().get(), 42);
1033
1034 let entry = Entry::<u64>::new(map.entry(key));
1036 entry.and_modify(|v| *v += 10).or_default();
1037
1038 let entry = Entry::<u64>::new(map.entry(key));
1039 assert_eq!(*entry.or_default().get(), 52);
1040 }
1041
1042 #[test]
1043 fn test_entry_pattern_matching() {
1044 let local: ActorLocal<u64> = ActorLocal::new();
1045 let storage = ActorLocalStorage::new();
1046 let map = storage.map();
1047 let key = local.key();
1048
1049 let entry = Entry::<u64>::new(map.entry(key));
1051 match entry {
1052 Entry::Vacant(v) => {
1053 v.insert(100);
1054 }
1055 Entry::Occupied(_) => panic!("expected vacant"),
1056 }
1057
1058 let entry = Entry::<u64>::new(map.entry(key));
1060 match entry {
1061 Entry::Occupied(mut o) => {
1062 assert_eq!(*o.get(), 100);
1063 *o.get_mut() = 200;
1064 }
1065 Entry::Vacant(_) => panic!("expected occupied"),
1066 }
1067
1068 let entry = Entry::<u64>::new(map.entry(key));
1070 assert_eq!(*entry.or_default().get(), 200);
1071
1072 let entry = Entry::<u64>::new(map.entry(key));
1074 match entry {
1075 Entry::Occupied(o) => {
1076 assert_eq!(o.remove(), 200);
1077 }
1078 Entry::Vacant(_) => panic!("expected occupied"),
1079 }
1080
1081 let entry = Entry::<u64>::new(map.entry(key));
1083 assert!(matches!(entry, Entry::Vacant(_)));
1084 }
1085
1086 #[test]
1087 fn test_occupied_entry_insert() {
1088 let local: ActorLocal<String> = ActorLocal::new();
1089 let storage = ActorLocalStorage::new();
1090 let map = storage.map();
1091 let key = local.key();
1092
1093 let entry = Entry::<String>::new(map.entry(key));
1095 entry.or_insert("hello".to_string());
1096
1097 let entry = Entry::<String>::new(map.entry(key));
1099 match entry {
1100 Entry::Occupied(mut o) => {
1101 let old = o.insert("world".to_string());
1102 assert_eq!(old, "hello");
1103 }
1104 Entry::Vacant(_) => panic!("expected occupied"),
1105 }
1106
1107 let entry = Entry::<String>::new(map.entry(key));
1109 assert_eq!(*entry.or_insert("".to_string()).get(), "world");
1110 }
1111}