|
1 |
| -use crate::lock::{RwLockReadGuardDetached, RwLockWriteGuardDetached}; |
| 1 | +use crate::{ |
| 2 | + lock::{RwLockReadGuardDetached, RwLockWriteGuardDetached}, |
| 3 | + mapref::multiple::{RefMulti, RefMutMulti}, |
| 4 | +}; |
2 | 5 | use core::hash::Hash;
|
3 | 6 | use core::ops::{Deref, DerefMut};
|
4 |
| -use std::fmt::{Debug, Formatter}; |
| 7 | +use std::{ |
| 8 | + fmt::{Debug, Formatter}, |
| 9 | + sync::Arc, |
| 10 | +}; |
5 | 11 |
|
6 | 12 | pub struct Ref<'a, K, V> {
|
7 | 13 | _guard: RwLockReadGuardDetached<'a>,
|
@@ -55,6 +61,29 @@ impl<'a, K: Eq + Hash, V> Ref<'a, K, V> {
|
55 | 61 | Err(self)
|
56 | 62 | }
|
57 | 63 | }
|
| 64 | + |
| 65 | + pub fn map_split<F, A: ?Sized, B: ?Sized>( |
| 66 | + self, |
| 67 | + f: F, |
| 68 | + ) -> (RefMulti<'a, K, A>, RefMulti<'a, K, B>) |
| 69 | + where |
| 70 | + F: FnOnce(&V) -> (&A, &B), |
| 71 | + { |
| 72 | + let (a, b) = f(self.v); |
| 73 | + let guard = Arc::new(self._guard); |
| 74 | + ( |
| 75 | + RefMulti { |
| 76 | + _guard: guard.clone(), |
| 77 | + k: self.k, |
| 78 | + v: a, |
| 79 | + }, |
| 80 | + RefMulti { |
| 81 | + _guard: guard, |
| 82 | + k: self.k, |
| 83 | + v: b, |
| 84 | + }, |
| 85 | + ) |
| 86 | + } |
58 | 87 | }
|
59 | 88 |
|
60 | 89 | impl<'a, K: Eq + Hash + Debug, V: Debug> Debug for Ref<'a, K, V> {
|
@@ -140,6 +169,29 @@ impl<'a, K: Eq + Hash, V> RefMut<'a, K, V> {
|
140 | 169 | v,
|
141 | 170 | })
|
142 | 171 | }
|
| 172 | + |
| 173 | + pub fn map_split<F, A: ?Sized, B: ?Sized>( |
| 174 | + self, |
| 175 | + f: F, |
| 176 | + ) -> (RefMutMulti<'a, K, A>, RefMutMulti<'a, K, B>) |
| 177 | + where |
| 178 | + F: FnOnce(&mut V) -> (&mut A, &mut B), |
| 179 | + { |
| 180 | + let (a, b) = f(self.v); |
| 181 | + let guard = Arc::new(self.guard); |
| 182 | + ( |
| 183 | + RefMutMulti { |
| 184 | + _guard: guard.clone(), |
| 185 | + k: self.k, |
| 186 | + v: a, |
| 187 | + }, |
| 188 | + RefMutMulti { |
| 189 | + _guard: guard, |
| 190 | + k: self.k, |
| 191 | + v: b, |
| 192 | + }, |
| 193 | + ) |
| 194 | + } |
143 | 195 | }
|
144 | 196 |
|
145 | 197 | impl<'a, K: Eq + Hash + Debug, V: Debug> Debug for RefMut<'a, K, V> {
|
@@ -373,6 +425,34 @@ mod tests {
|
373 | 425 | };
|
374 | 426 | }
|
375 | 427 |
|
| 428 | + #[test] |
| 429 | + fn ref_map_split() { |
| 430 | + struct Data(String, String); |
| 431 | + let data = DashMap::new(); |
| 432 | + data.insert("test", Data("hello".to_string(), "world".to_string())); |
| 433 | + if let Some(b_ref) = data.get("test") { |
| 434 | + let (l_ref, r_ref) = b_ref.map_split(|d| (&d.0, &d.1)); |
| 435 | + |
| 436 | + assert_eq!(l_ref.value(), "hello"); |
| 437 | + assert_eq!(r_ref.value(), "world"); |
| 438 | + }; |
| 439 | + } |
| 440 | + |
| 441 | + #[test] |
| 442 | + fn ref_mut_map_split() { |
| 443 | + let data = DashMap::new(); |
| 444 | + data.insert("test", "hello world".to_string()); |
| 445 | + if let Some(b_ref) = data.get_mut("test") { |
| 446 | + let (mut l_ref, r_ref) = b_ref.map_split(|d| d.split_at_mut(5)); |
| 447 | + |
| 448 | + assert_eq!(l_ref.value(), "hello"); |
| 449 | + assert_eq!(r_ref.value(), " world"); |
| 450 | + l_ref.make_ascii_uppercase(); |
| 451 | + }; |
| 452 | + let Some(b_ref) = data.get("test") else { panic!("") }; |
| 453 | + assert_eq!(b_ref.value(), "HELLO world"); |
| 454 | + } |
| 455 | + |
376 | 456 | #[test]
|
377 | 457 | fn mapped_ref_again() {
|
378 | 458 | let data = DashMap::new();
|
|
0 commit comments