Skip to main content

rust_key_paths/
lock.rs

1//! # Lock Keypath Module
2//!
3//! This module provides `LockKp` for safely navigating through locked/synchronized data structures.
4//!
5//! # Naming convention (aligned with [crate::Kp] and [crate::async_lock])
6//!
7//! - **`then`** – chain with a plain [crate::Kp]
8//! - **`then_lock`** – chain with another [LockKp] for multi-level lock access
9//!
10//! # SHALLOW CLONING GUARANTEE & NO UNNECESSARY CLONES
11//!
12//! **IMPORTANT**: All cloning operations in this module are SHALLOW (reference-counted) clones:
13//!
14//! 1. **`LockKp` derives `Clone`**: Clones function pointers and PhantomData only
15//!    - `prev` and `next` fields contain function pointers (cheap to copy)
16//!    - `mid` field is typically just `PhantomData<T>` (zero-sized, zero-cost)
17//!    - No heap allocations or deep data copies
18//!
19//! 2. **NO `Lock: Clone` required for most operations**:
20//!    - `lock_write` takes `&Lock` (not `&mut Lock`) due to interior mutability
21//!    - For `Arc<Mutex<T>>`: No cloning needed, we just use `&Arc<...>`
22//!    - The actual data `T` inside is **NEVER** cloned during lock operations
23//!    - This eliminates unnecessary Arc reference count increments
24//!
25//! 3. **`L: Clone` bound** (e.g., `ArcMutexAccess<T>`):
26//!    - Only clones `PhantomData<T>` which is zero-sized
27//!    - Compiled away completely - zero runtime cost
28//!
29//! ## Performance Characteristics
30//!
31//! - `LockKp::clone()`: O(1) - copies a few pointers
32//! - `ArcMutexAccess::clone()`: O(1) - no-op (zero-sized type)
33//! - **Lock operations**: No Arc cloning needed - direct reference use
34//! - **Total**: All operations are constant-time with no deep copying
35//!
36//! ## Memory Safety
37//!
38//! The design is safe because:
39//! - Locks provide interior mutability (no `&mut` needed for write operations)
40//! - `Arc` provides thread-safe reference counting
41//! - `Mutex` ensures exclusive access when needed
42//! - No dangling pointers or use-after-free possible
43//! - Rust's ownership system enforces correctness
44
45use crate::Kp;
46use std::sync::{Arc, Mutex};
47
48/// Trait for types that can provide lock/unlock behavior
49/// Converts from a Lock type to Inner or InnerMut value
50pub trait LockAccess<Lock, Inner> {
51    /// Get immutable access to the inner value
52    fn lock_read(&self, lock: &Lock) -> Option<Inner>;
53
54    /// Get mutable access to the inner value
55    ///
56    /// Note: Takes `&Lock` not `&mut Lock` because locks like Mutex/RwLock
57    /// provide interior mutability - we don't need exclusive access to the
58    /// lock container itself, just to the data inside.
59    fn lock_write(&self, lock: &Lock) -> Option<Inner>;
60}
61
62/// A keypath that handles locked values (e.g., Arc<Mutex<T>>)
63///
64/// Structure:
65/// - `prev`: Keypath from Root to Lock container (e.g., Arc<Mutex<Mid>>)
66/// - `mid`: Lock access handler that goes from Lock to Inner value
67/// - `next`: Keypath from Inner value to final Value
68///
69/// # Type Parameters
70/// - `R`: Root type (base)
71/// - `Lock`: Lock container type (e.g., Arc<Mutex<Mid>>)
72/// - `Mid`: The type inside the lock
73/// - `V`: Final value type
74/// - Rest are the same generic parameters as Kp
75///
76/// # Cloning Behavior
77///
78/// **IMPORTANT**: All `Clone` operations in this struct are SHALLOW clones:
79///
80/// - `LockKp` itself derives `Clone` - this clones the three field references/closures
81/// - `prev` and `next` fields are `Kp` structs containing function pointers (cheap to clone)
82/// - `mid` field implements `LockAccess` trait - typically just `PhantomData` (zero-cost clone)
83/// - NO `Lock: Clone` needed for lock operations - we use `&Lock` directly via interior mutability
84/// - NO deep data cloning occurs - all clones are pointer/reference copies
85///
86/// # Example
87/// ```ignore
88/// use std::sync::{Arc, Mutex};
89/// use rust_key_paths::lock::{ArcMutexAccess, LockKp};
90/// use rust_key_paths::Kp;
91///
92/// struct Root {
93///     data: Arc<Mutex<Inner>>,
94/// }
95///
96/// struct Inner {
97///     value: String,
98/// }
99///
100/// // Create a LockKp that goes: Root -> Arc<Mutex<Inner>> -> String
101/// let root_to_lock_kp = Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
102/// let inner_to_value_kp = Kp::new(|i: &Inner| Some(&i.value), |i: &mut Inner| Some(&mut i.value));
103/// let lock_kp = LockKp::new(root_to_lock_kp, ArcMutexAccess::new(), inner_to_value_kp);
104/// ```
105#[derive(Clone)] // SHALLOW: Clones function pointers and PhantomData only
106pub struct LockKp<
107    R,
108    Lock,
109    Mid,
110    V,
111    Root,
112    LockValue,
113    MidValue,
114    Value,
115    MutRoot,
116    MutLock,
117    MutMid,
118    MutValue,
119    G1,
120    S1,
121    L,
122    G2,
123    S2,
124> where
125    Root: std::borrow::Borrow<R>,
126    LockValue: std::borrow::Borrow<Lock>,
127    MidValue: std::borrow::Borrow<Mid>,
128    Value: std::borrow::Borrow<V>,
129    MutRoot: std::borrow::BorrowMut<R>,
130    MutLock: std::borrow::BorrowMut<Lock>,
131    MutMid: std::borrow::BorrowMut<Mid>,
132    MutValue: std::borrow::BorrowMut<V>,
133    G1: Fn(Root) -> Option<LockValue>,
134    S1: Fn(MutRoot) -> Option<MutLock>,
135    L: LockAccess<Lock, MidValue> + LockAccess<Lock, MutMid>,
136    G2: Fn(MidValue) -> Option<Value>,
137    S2: Fn(MutMid) -> Option<MutValue>,
138{
139    /// Keypath from Root to Lock container
140    pub(crate) prev: Kp<R, Lock, Root, LockValue, MutRoot, MutLock, G1, S1>,
141
142    /// Lock access handler (converts Lock -> Inner)
143    pub(crate) mid: L,
144
145    /// Keypath from Inner to final Value
146    pub(crate) next: Kp<Mid, V, MidValue, Value, MutMid, MutValue, G2, S2>,
147}
148
149impl<
150    R,
151    Lock,
152    Mid,
153    V,
154    Root,
155    LockValue,
156    MidValue,
157    Value,
158    MutRoot,
159    MutLock,
160    MutMid,
161    MutValue,
162    G1,
163    S1,
164    L,
165    G2,
166    S2,
167>
168    LockKp<
169        R,
170        Lock,
171        Mid,
172        V,
173        Root,
174        LockValue,
175        MidValue,
176        Value,
177        MutRoot,
178        MutLock,
179        MutMid,
180        MutValue,
181        G1,
182        S1,
183        L,
184        G2,
185        S2,
186    >
187where
188    Root: std::borrow::Borrow<R>,
189    LockValue: std::borrow::Borrow<Lock>,
190    MidValue: std::borrow::Borrow<Mid>,
191    Value: std::borrow::Borrow<V>,
192    MutRoot: std::borrow::BorrowMut<R>,
193    MutLock: std::borrow::BorrowMut<Lock>,
194    MutMid: std::borrow::BorrowMut<Mid>,
195    MutValue: std::borrow::BorrowMut<V>,
196    G1: Fn(Root) -> Option<LockValue>,
197    S1: Fn(MutRoot) -> Option<MutLock>,
198    L: LockAccess<Lock, MidValue> + LockAccess<Lock, MutMid>,
199    G2: Fn(MidValue) -> Option<Value>,
200    S2: Fn(MutMid) -> Option<MutValue>,
201{
202    /// Create a new LockKp with prev, mid, and next components
203    pub fn new(
204        prev: Kp<R, Lock, Root, LockValue, MutRoot, MutLock, G1, S1>,
205        mid: L,
206        next: Kp<Mid, V, MidValue, Value, MutMid, MutValue, G2, S2>,
207    ) -> Self {
208        Self { prev, mid, next }
209    }
210
211    /// Get an immutable reference through the lock (sync, blocking).
212    ///
213    /// This will:
214    /// 1. Use `prev` to get to the Lock
215    /// 2. Use `mid` to lock and get Inner value
216    /// 3. Use `next` to get from Inner to final Value
217    ///
218    /// # Example
219    /// ```
220    /// use rust_key_paths::{KpType, LockKp};
221    /// use std::sync::Mutex;
222    ///
223    /// #[derive(key_paths_derive::Kp)]
224    /// struct WithLocks {
225    ///     std_mutex: std::sync::Mutex<i32>,
226    ///     std_rwlock: std::sync::RwLock<String>,
227    /// }
228    ///
229    /// let locks = WithLocks {
230    ///     std_mutex: Mutex::new(99),
231    ///     std_rwlock: std::sync::RwLock::new("test".to_string()),
232    /// };
233    /// let mutex_kp = WithLocks::std_mutex();
234    /// let rwlock_kp = WithLocks::std_rwlock();
235    /// let next: KpType<i32, i32> = rust_key_paths::Kp::new(|i: &i32| Some(i), |i: &mut i32| Some(i));
236    /// let lock_kp = LockKp::new(mutex_kp, rust_key_paths::StdMutexAccess::new(), next);
237    ///
238    /// let value = lock_kp.get(&locks);
239    /// assert_eq!(value, Some(&99));
240    /// ```
241    ///
242    /// # Cloning Behavior
243    /// Only requires `V: Clone` for the final value.
244    /// NO `Lock: Clone` needed because `lock_read` takes `&Lock`.
245    #[inline]
246    pub fn get(&self, root: Root) -> Option<Value>
247    where
248        V: Clone,
249    {
250        (self.prev.get)(root).and_then(|lock_value| {
251            let lock: &Lock = lock_value.borrow();
252            self.mid
253                .lock_read(lock)
254                .and_then(|mid_value| (self.next.get)(mid_value))
255        })
256    }
257
258    /// Get mutable access to the value through the lock (sync, blocking).
259    ///
260    /// # Example
261    /// ```
262    /// use rust_key_paths::{KpType, LockKp};
263    /// use std::sync::Mutex;
264    ///
265    /// #[derive(key_paths_derive::Kp)]
266    /// struct WithLocks {
267    ///     std_mutex: std::sync::Mutex<i32>,
268    ///     std_rwlock: std::sync::RwLock<String>,
269    /// }
270    ///
271    /// let mut locks = WithLocks {
272    ///     std_mutex: Mutex::new(99),
273    ///     std_rwlock: std::sync::RwLock::new("test".to_string()),
274    /// };
275    /// let mutex_kp = WithLocks::std_mutex();
276    /// let next: KpType<i32, i32> = rust_key_paths::Kp::new(|i: &i32| Some(i), |i: &mut i32| Some(i));
277    /// let lock_kp = LockKp::new(mutex_kp, rust_key_paths::StdMutexAccess::new(), next);
278    ///
279    /// let value = lock_kp.get_mut(&mut locks).unwrap();
280    /// *value = 42;
281    /// assert_eq!(*locks.std_mutex.lock().unwrap(), 42);
282    /// ```
283    ///
284    /// # NO CLONING Required!
285    ///
286    /// No longer needs `Lock: Clone` because `lock_write` now takes `&Lock` instead of `&mut Lock`
287    #[inline]
288    pub fn get_mut(&self, root: MutRoot) -> Option<MutValue> {
289        (self.prev.set)(root).and_then(|mut lock_value| {
290            let lock: &Lock = lock_value.borrow();
291            self.mid
292                .lock_write(lock)
293                .and_then(|mid_value| (self.next.set)(mid_value))
294        })
295    }
296
297    /// Like [get](LockKp::get), but takes an optional root: returns `None` if `root` is `None`, otherwise the result of the getter.
298    #[inline]
299    pub fn get_optional(&self, root: Option<Root>) -> Option<Value>
300    where
301        V: Clone,
302    {
303        root.and_then(|r| self.get(r))
304    }
305
306    /// Like [get_mut](LockKp::get_mut), but takes an optional root: returns `None` if `root` is `None`, otherwise the result of the setter.
307    #[inline]
308    pub fn get_mut_optional(&self, root: Option<MutRoot>) -> Option<MutValue> {
309        root.and_then(|r| self.get_mut(r))
310    }
311
312    /// Returns the value if the keypath succeeds (root is `Some` and get returns `Some`), otherwise calls `f` and returns its result.
313    #[inline]
314    pub fn get_or_else<F>(&self, root: Option<Root>, f: F) -> Value
315    where
316        V: Clone,
317        F: FnOnce() -> Value,
318    {
319        self.get_optional(root).unwrap_or_else(f)
320    }
321
322    /// Returns the mutable value if the keypath succeeds (root is `Some` and get_mut returns `Some`), otherwise calls `f` and returns its result.
323    #[inline]
324    pub fn get_mut_or_else<F>(&self, root: Option<MutRoot>, f: F) -> MutValue
325    where
326        F: FnOnce() -> MutValue,
327    {
328        self.get_mut_optional(root).unwrap_or_else(f)
329    }
330
331    /// Set the value through the lock using an updater function
332    ///
333    /// # NO CLONING Required!
334    ///
335    /// Unlike the original implementation, we NO LONGER need `Lock: Clone` because:
336    /// - Locks like `Mutex` and `RwLock` provide interior mutability
337    /// - We only need `&Lock`, not `&mut Lock`, to get mutable access to the inner data
338    /// - This eliminates an unnecessary Arc reference count increment
339    pub fn set<F>(&self, root: Root, updater: F) -> Result<(), String>
340    where
341        F: FnOnce(&mut V),
342        MutValue: std::borrow::BorrowMut<V>,
343    {
344        (self.prev.get)(root)
345            .ok_or_else(|| "Failed to get lock container".to_string())
346            .and_then(|lock_value| {
347                let lock: &Lock = lock_value.borrow();
348                // NO CLONE NEEDED! lock_write now takes &Lock instead of &mut Lock
349                self.mid
350                    .lock_write(lock)
351                    .ok_or_else(|| "Failed to lock".to_string())
352                    .and_then(|mid_value| {
353                        (self.next.set)(mid_value)
354                            .ok_or_else(|| "Failed to get value".to_string())
355                            .map(|mut value| {
356                                updater(value.borrow_mut());
357                            })
358                    })
359            })
360    }
361
362    /// Chain this LockKp with another regular Kp
363    ///
364    /// This allows you to continue navigating after getting through the lock:
365    /// Root -> Lock -> Mid -> Value1 -> Value2
366    ///
367    /// # Cloning Behavior
368    /// No cloning occurs in this method - closures are moved into the new Kp
369    pub fn then<V2, Value2, MutValue2, G3, S3>(
370        self,
371        next_kp: Kp<V, V2, Value, Value2, MutValue, MutValue2, G3, S3>,
372    ) -> LockKp<
373        R,
374        Lock,
375        Mid,
376        V2,
377        Root,
378        LockValue,
379        MidValue,
380        Value2,
381        MutRoot,
382        MutLock,
383        MutMid,
384        MutValue2,
385        G1,
386        S1,
387        L,
388        impl Fn(MidValue) -> Option<Value2> + use<G1, G2, G3, L, Lock, LockValue, Mid, MidValue, MutLock, MutMid, MutRoot, MutValue, MutValue2, R, Root, S1, S2, S3, Value, Value2, V, V2>,
389        impl Fn(MutMid) -> Option<MutValue2> + use<G1, G2, G3, L, Lock, LockValue, Mid, MidValue, MutLock, MutMid, MutRoot, MutValue, MutValue2, R, Root, S1, S2, S3, Value, Value2, V, V2>,
390    >
391    where
392        V: 'static,
393        V2: 'static,
394        Value: std::borrow::Borrow<V>,
395        Value2: std::borrow::Borrow<V2>,
396        MutValue: std::borrow::BorrowMut<V>,
397        MutValue2: std::borrow::BorrowMut<V2>,
398        G3: Fn(Value) -> Option<Value2> + 'static,
399        S3: Fn(MutValue) -> Option<MutValue2> + 'static,
400    {
401        // Extract closures (move, no clone)
402        let next_get = self.next.get;
403        let next_set = self.next.set;
404
405        // Create chained keypath by composing closures (no cloning)
406        let chained_kp = Kp::new(
407            move |mid_value: MidValue| next_get(mid_value).and_then(|v| (next_kp.get)(v)),
408            move |mid_value: MutMid| next_set(mid_value).and_then(|v| (next_kp.set)(v)),
409        );
410
411        LockKp::new(self.prev, self.mid, chained_kp)
412    }
413
414    /// Chain with another LockKp for multi-level lock access (then_lock convention)
415    ///
416    /// This allows you to chain through multiple lock levels:
417    /// Root -> Lock1 -> Mid1 -> Lock2 -> Mid2 -> Value
418    ///
419    /// # Cloning Behavior - ALL CLONES ARE SHALLOW
420    ///
421    /// This method requires two types of cloning, both SHALLOW:
422    ///
423    /// 1. **`L2: Clone`**: Clones the lock accessor (typically PhantomData)
424    ///    - For `ArcMutexAccess<T>`: Only clones `PhantomData` (zero-cost)
425    ///    - No data is cloned, just the lock access behavior
426    ///
427    /// 2. **NO `Lock2: Clone` needed**: Uses `&Lock2` reference directly (interior mutability)
428    ///
429    /// **Performance**: Only L2 (lock accessor) is cloned—O(1), typically zero-cost PhantomData
430    ///
431    /// # Example
432    /// ```ignore
433    /// // Root -> Arc<Mutex<Mid1>> -> Mid1 -> Arc<Mutex<Mid2>> -> Mid2 -> String
434    /// let lock_kp1 = LockKp::new(root_to_lock1, ArcMutexAccess::new(), lock1_to_mid1);
435    /// let lock_kp2 = LockKp::new(mid1_to_lock2, ArcMutexAccess::new(), mid2_to_value);
436    ///
437    /// let chained = lock_kp1.then_lock(lock_kp2);
438    /// ```
439    pub fn then_lock<
440        Lock2,
441        Mid2,
442        V2,
443        LockValue2,
444        MidValue2,
445        Value2,
446        MutLock2,
447        MutMid2,
448        MutValue2,
449        G2_1,
450        S2_1,
451        L2,
452        G2_2,
453        S2_2,
454    >(
455        self,
456        other: LockKp<
457            V,
458            Lock2,
459            Mid2,
460            V2,
461            Value,
462            LockValue2,
463            MidValue2,
464            Value2,
465            MutValue,
466            MutLock2,
467            MutMid2,
468            MutValue2,
469            G2_1,
470            S2_1,
471            L2,
472            G2_2,
473            S2_2,
474        >,
475    ) -> LockKp<
476        R,
477        Lock,
478        Mid,
479        V2,
480        Root,
481        LockValue,
482        MidValue,
483        Value2,
484        MutRoot,
485        MutLock,
486        MutMid,
487        MutValue2,
488        G1,
489        S1,
490        L,
491        impl Fn(MidValue) -> Option<Value2> + use<G1, G2, G2_1, G2_2, L, L2, Lock, Lock2, LockValue, LockValue2, Mid, Mid2, MidValue, MidValue2, MutLock, MutLock2, MutMid, MutMid2, MutRoot, MutValue, MutValue2, R, Root, S1, S2, S2_1, S2_2, Value, Value2, V, V2>,
492        impl Fn(MutMid) -> Option<MutValue2> + use<G1, G2, G2_1, G2_2, L, L2, Lock, Lock2, LockValue, LockValue2, Mid, Mid2, MidValue, MidValue2, MutLock, MutLock2, MutMid, MutMid2, MutRoot, MutValue, MutValue2, R, Root, S1, S2, S2_1, S2_2, Value, Value2, V, V2>,
493    >
494    where
495        V: 'static + Clone,
496        V2: 'static,
497        Value: std::borrow::Borrow<V>,
498        LockValue2: std::borrow::Borrow<Lock2>,
499        MidValue2: std::borrow::Borrow<Mid2>,
500        Value2: std::borrow::Borrow<V2>,
501        MutValue: std::borrow::BorrowMut<V>,
502        MutLock2: std::borrow::BorrowMut<Lock2>,
503        MutMid2: std::borrow::BorrowMut<Mid2>,
504        MutValue2: std::borrow::BorrowMut<V2>,
505        G2_1: Fn(Value) -> Option<LockValue2> + 'static,
506        S2_1: Fn(MutValue) -> Option<MutLock2> + 'static,
507        L2: LockAccess<Lock2, MidValue2> + LockAccess<Lock2, MutMid2> + Clone + 'static, // SHALLOW: PhantomData clone
508        G2_2: Fn(MidValue2) -> Option<Value2> + 'static,
509        S2_2: Fn(MutMid2) -> Option<MutValue2> + 'static,
510    {
511        // Extract closures from self (move, no clone)
512        let next_get = self.next.get;
513        let next_set = self.next.set;
514
515        // Extract closures from other (move, no clone)
516        let other_prev_get = other.prev.get;
517        let other_prev_set = other.prev.set;
518
519        // SHALLOW CLONE: Clone the lock accessor (typically just PhantomData)
520        // For ArcMutexAccess<T>, this is a zero-cost clone of PhantomData
521        let other_mid1 = other.mid.clone();
522        let other_mid2 = other.mid;
523
524        let other_next_get = other.next.get;
525        let other_next_set = other.next.set;
526
527        // Create a composed keypath: Mid -> Lock2 -> Mid2 -> Value2
528        let composed_kp = Kp::new(
529            move |mid_value: MidValue| {
530                // First, navigate from Mid to V using self.next
531                next_get(mid_value).and_then(|value1| {
532                    // Then navigate from V to Lock2 using other.prev
533                    other_prev_get(value1).and_then(|lock2_value| {
534                        let lock2: &Lock2 = lock2_value.borrow();
535                        // Lock and get Mid2 using other.mid (no clone here)
536                        other_mid1.lock_read(lock2).and_then(|mid2_value| {
537                            // Finally navigate from Mid2 to Value2 using other.next
538                            other_next_get(mid2_value)
539                        })
540                    })
541                })
542            },
543            move |mid_value: MutMid| {
544                // Same flow but for mutable access
545                next_set(mid_value).and_then(|value1| {
546                    other_prev_set(value1).and_then(|lock2_value| {
547                        let lock2: &Lock2 = lock2_value.borrow();
548                        other_mid2
549                            .lock_write(lock2)
550                            .and_then(|mid2_value| other_next_set(mid2_value))
551                    })
552                })
553            },
554        );
555
556        LockKp::new(self.prev, self.mid, composed_kp)
557    }
558
559    /// Chain with an async keypath. Use `.get(&root).await` on the returned keypath.
560    /// When `AsyncKp::Value` is a reference type (`&T` / `&mut T`), `V2` is inferred as `T` via [crate::KeyPathValueTarget].
561    pub fn then_async<AsyncKp>(
562        self,
563        async_kp: AsyncKp,
564    ) -> crate::async_lock::KpThenAsyncKeyPath<
565        R,
566        V,
567        <AsyncKp::Value as crate::KeyPathValueTarget>::Target,
568        Root,
569        Value,
570        AsyncKp::Value,
571        MutRoot,
572        MutValue,
573        AsyncKp::MutValue,
574        Self,
575        AsyncKp,
576    >
577    where
578        V: 'static + Clone,
579        Value: std::borrow::Borrow<V>,
580        MutValue: std::borrow::BorrowMut<V>,
581        AsyncKp: crate::async_lock::AsyncKeyPathLike<Value, MutValue>,
582        AsyncKp::Value: crate::KeyPathValueTarget
583            + std::borrow::Borrow<<AsyncKp::Value as crate::KeyPathValueTarget>::Target>,
584        AsyncKp::MutValue: std::borrow::BorrowMut<<AsyncKp::Value as crate::KeyPathValueTarget>::Target>,
585        <AsyncKp::Value as crate::KeyPathValueTarget>::Target: 'static,
586    {
587        crate::async_lock::KpThenAsyncKeyPath {
588            first: self,
589            second: async_kp,
590            _p: std::marker::PhantomData,
591        }
592    }
593}
594
595// ============================================================================
596// KpThenLockKp: Kp .then_lock(LockKp) — sync keypath then sync lock
597// ============================================================================
598
599/// Keypath that chains a [crate::Kp] with a [LockKp]. Use [crate::Kp::then_lock] to create.
600#[derive(Clone)]
601pub struct KpThenLockKp<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second> {
602    pub(crate) first: First,
603    pub(crate) second: Second,
604    pub(crate) _p: std::marker::PhantomData<(R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2)>,
605}
606
607impl<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
608    KpThenLockKp<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, First, Second>
609where
610    First: crate::async_lock::SyncKeyPathLike<Root, Value, MutRoot, MutValue>,
611    Second: crate::async_lock::SyncKeyPathLike<Value, Value2, MutValue, MutValue2>,
612{
613    /// Get through first keypath then second (sync).
614    #[inline]
615    pub fn get(&self, root: Root) -> Option<Value2>
616    where
617        Value2: Clone,
618    {
619        let v = self.first.sync_get(root)?;
620        self.second.sync_get(v)
621    }
622    /// Get mutable through first then second (sync).
623    #[inline]
624    pub fn get_mut(&self, root: MutRoot) -> Option<MutValue2> {
625        let mut_v = self.first.sync_get_mut(root)?;
626        self.second.sync_get_mut(mut_v)
627    }
628
629    /// Like [get](KpThenLockKp::get), but takes an optional root.
630    #[inline]
631    pub fn get_optional(&self, root: Option<Root>) -> Option<Value2>
632    where
633        Value2: Clone,
634    {
635        root.and_then(|r| self.get(r))
636    }
637
638    /// Like [get_mut](KpThenLockKp::get_mut), but takes an optional root.
639    #[inline]
640    pub fn get_mut_optional(&self, root: Option<MutRoot>) -> Option<MutValue2> {
641        root.and_then(|r| self.get_mut(r))
642    }
643
644    /// Returns the value if the keypath succeeds, otherwise calls `f` and returns its result.
645    #[inline]
646    pub fn get_or_else<F>(&self, root: Option<Root>, f: F) -> Value2
647    where
648        Value2: Clone,
649        F: FnOnce() -> Value2,
650    {
651        self.get_optional(root).unwrap_or_else(f)
652    }
653
654    /// Returns the mutable value if the keypath succeeds, otherwise calls `f` and returns its result.
655    #[inline]
656    pub fn get_mut_or_else<F>(&self, root: Option<MutRoot>, f: F) -> MutValue2
657    where
658        F: FnOnce() -> MutValue2,
659    {
660        self.get_mut_optional(root).unwrap_or_else(f)
661    }
662}
663
664// ============================================================================
665// Standard Lock Access Implementations
666// ============================================================================
667
668/// Lock access implementation for Arc<Mutex<T>>
669///
670/// # Cloning Behavior
671///
672/// This struct only contains `PhantomData<T>`, which is a zero-sized type.
673/// Cloning `ArcMutexAccess<T>` is a **zero-cost operation** - no data is copied.
674///
675/// The `Clone` impl is required for the `then_lock()` method to work, but it's
676/// completely free (compiled away to nothing).
677#[derive(Clone)] // ZERO-COST: Only clones PhantomData (zero-sized type)
678pub struct ArcMutexAccess<T> {
679    _phantom: std::marker::PhantomData<T>, // Zero-sized, no runtime cost
680}
681
682impl<T> ArcMutexAccess<T> {
683    pub fn new() -> Self {
684        Self {
685            _phantom: std::marker::PhantomData,
686        }
687    }
688}
689
690impl<T> Default for ArcMutexAccess<T> {
691    fn default() -> Self {
692        Self::new()
693    }
694}
695
696// Implementation for immutable access (returns reference to locked value)
697impl<'a, T: 'static> LockAccess<Arc<Mutex<T>>, &'a T> for ArcMutexAccess<T> {
698    #[inline]
699    fn lock_read(&self, lock: &Arc<Mutex<T>>) -> Option<&'a T> {
700        // Note: This is a simplified implementation
701        // In practice, returning a reference from a MutexGuard is tricky
702        // This works for the pattern but may need adjustment for real usage
703        lock.lock().ok().map(|guard| {
704            let ptr = &*guard as *const T;
705            unsafe { &*ptr }
706        })
707    }
708
709    #[inline]
710    fn lock_write(&self, lock: &Arc<Mutex<T>>) -> Option<&'a T> {
711        lock.lock().ok().map(|guard| {
712            let ptr = &*guard as *const T;
713            unsafe { &*ptr }
714        })
715    }
716}
717
718// Implementation for mutable access
719impl<'a, T: 'static> LockAccess<Arc<Mutex<T>>, &'a mut T> for ArcMutexAccess<T> {
720    #[inline]
721    fn lock_read(&self, lock: &Arc<Mutex<T>>) -> Option<&'a mut T> {
722        lock.lock().ok().map(|mut guard| {
723            let ptr = &mut *guard as *mut T;
724            unsafe { &mut *ptr }
725        })
726    }
727
728    #[inline]
729    fn lock_write(&self, lock: &Arc<Mutex<T>>) -> Option<&'a mut T> {
730        lock.lock().ok().map(|mut guard| {
731            let ptr = &mut *guard as *mut T;
732            unsafe { &mut *ptr }
733        })
734    }
735}
736
737// ============================================================================
738// RwLock Access Implementation
739// ============================================================================
740
741/// Lock access implementation for Arc<RwLock<T>>
742///
743/// # RwLock Semantics
744///
745/// `RwLock` provides reader-writer lock semantics:
746/// - Multiple readers can access simultaneously (shared/immutable access)
747/// - Only one writer can access at a time (exclusive/mutable access)
748/// - Readers and writers are mutually exclusive
749///
750/// # Cloning Behavior
751///
752/// Like `ArcMutexAccess`, this struct only contains `PhantomData<T>`.
753/// Cloning is a **zero-cost operation** - no data is copied.
754///
755/// # Performance vs Mutex
756///
757/// - **Better for read-heavy workloads**: Multiple concurrent readers
758/// - **Slightly more overhead**: RwLock has more complex internal state
759/// - **Use when**: Many readers, few writers
760/// - **Avoid when**: Frequent writes or simple cases (use Mutex)
761#[derive(Clone)] // ZERO-COST: Only clones PhantomData (zero-sized type)
762pub struct ArcRwLockAccess<T> {
763    _phantom: std::marker::PhantomData<T>, // Zero-sized, no runtime cost
764}
765
766impl<T> ArcRwLockAccess<T> {
767    pub fn new() -> Self {
768        Self {
769            _phantom: std::marker::PhantomData,
770        }
771    }
772}
773
774impl<T> Default for ArcRwLockAccess<T> {
775    fn default() -> Self {
776        Self::new()
777    }
778}
779
780// Implementation for immutable access (read lock)
781impl<'a, T: 'static> LockAccess<Arc<std::sync::RwLock<T>>, &'a T> for ArcRwLockAccess<T> {
782    fn lock_read(&self, lock: &Arc<std::sync::RwLock<T>>) -> Option<&'a T> {
783        // Acquire read lock - allows multiple concurrent readers
784        lock.read().ok().map(|guard| {
785            let ptr = &*guard as *const T;
786            unsafe { &*ptr }
787        })
788    }
789
790    fn lock_write(&self, lock: &Arc<std::sync::RwLock<T>>) -> Option<&'a T> {
791        // For immutable access, we still use read lock
792        lock.read().ok().map(|guard| {
793            let ptr = &*guard as *const T;
794            unsafe { &*ptr }
795        })
796    }
797}
798
799// Implementation for mutable access (write lock)
800impl<'a, T: 'static> LockAccess<Arc<std::sync::RwLock<T>>, &'a mut T> for ArcRwLockAccess<T> {
801    fn lock_read(&self, lock: &Arc<std::sync::RwLock<T>>) -> Option<&'a mut T> {
802        // For mutable access, we need write lock (exclusive)
803        lock.write().ok().map(|mut guard| {
804            let ptr = &mut *guard as *mut T;
805            unsafe { &mut *ptr }
806        })
807    }
808
809    fn lock_write(&self, lock: &Arc<std::sync::RwLock<T>>) -> Option<&'a mut T> {
810        // Acquire write lock - exclusive access
811        lock.write().ok().map(|mut guard| {
812            let ptr = &mut *guard as *mut T;
813            unsafe { &mut *ptr }
814        })
815    }
816}
817
818// ============================================================================
819// Direct Mutex Access Implementation (without Arc)
820// ============================================================================
821
822/// Lock access implementation for std::sync::Mutex<T> (without Arc wrapper)
823///
824/// # When to Use
825///
826/// Use this when you have a direct reference to a Mutex, not wrapped in Arc.
827/// Common scenarios:
828/// - Mutex is owned by a struct
829/// - Single-threaded or thread-local usage
830/// - When the Mutex lifetime is managed by other means
831///
832/// # Note
833///
834/// Since we're working with `&Mutex<T>`, this requires the Mutex to be
835/// stored somewhere with a stable address (e.g., in a struct, Box, or static).
836#[derive(Clone)]
837pub struct StdMutexAccess<T> {
838    _phantom: std::marker::PhantomData<T>,
839}
840
841impl<T> StdMutexAccess<T> {
842    pub fn new() -> Self {
843        Self {
844            _phantom: std::marker::PhantomData,
845        }
846    }
847}
848
849impl<T> Default for StdMutexAccess<T> {
850    fn default() -> Self {
851        Self::new()
852    }
853}
854
855// Implementation for immutable access
856impl<'a, T: 'static> LockAccess<Mutex<T>, &'a T> for StdMutexAccess<T> {
857    fn lock_read(&self, lock: &Mutex<T>) -> Option<&'a T> {
858        lock.lock().ok().map(|guard| {
859            let ptr = &*guard as *const T;
860            unsafe { &*ptr }
861        })
862    }
863
864    fn lock_write(&self, lock: &Mutex<T>) -> Option<&'a T> {
865        lock.lock().ok().map(|guard| {
866            let ptr = &*guard as *const T;
867            unsafe { &*ptr }
868        })
869    }
870}
871
872// Implementation for mutable access
873impl<'a, T: 'static> LockAccess<Mutex<T>, &'a mut T> for StdMutexAccess<T> {
874    fn lock_read(&self, lock: &Mutex<T>) -> Option<&'a mut T> {
875        lock.lock().ok().map(|mut guard| {
876            let ptr = &mut *guard as *mut T;
877            unsafe { &mut *ptr }
878        })
879    }
880
881    fn lock_write(&self, lock: &Mutex<T>) -> Option<&'a mut T> {
882        lock.lock().ok().map(|mut guard| {
883            let ptr = &mut *guard as *mut T;
884            unsafe { &mut *ptr }
885        })
886    }
887}
888
889// ============================================================================
890// Direct RwLock Access Implementation (without Arc)
891// ============================================================================
892
893/// Lock access implementation for std::sync::RwLock<T> (without Arc wrapper)
894///
895/// # RwLock Semantics
896///
897/// - Multiple concurrent readers allowed
898/// - Single exclusive writer
899/// - Better for read-heavy workloads
900///
901/// # When to Use
902///
903/// Use this when you have a direct reference to an RwLock, not wrapped in Arc.
904#[derive(Clone)]
905pub struct StdRwLockAccess<T> {
906    _phantom: std::marker::PhantomData<T>,
907}
908
909impl<T> StdRwLockAccess<T> {
910    pub fn new() -> Self {
911        Self {
912            _phantom: std::marker::PhantomData,
913        }
914    }
915}
916
917impl<T> Default for StdRwLockAccess<T> {
918    fn default() -> Self {
919        Self::new()
920    }
921}
922
923// Implementation for immutable access (read lock)
924impl<'a, T: 'static> LockAccess<std::sync::RwLock<T>, &'a T> for StdRwLockAccess<T> {
925    fn lock_read(&self, lock: &std::sync::RwLock<T>) -> Option<&'a T> {
926        lock.read().ok().map(|guard| {
927            let ptr = &*guard as *const T;
928            unsafe { &*ptr }
929        })
930    }
931
932    fn lock_write(&self, lock: &std::sync::RwLock<T>) -> Option<&'a T> {
933        lock.read().ok().map(|guard| {
934            let ptr = &*guard as *const T;
935            unsafe { &*ptr }
936        })
937    }
938}
939
940// Implementation for mutable access (write lock)
941impl<'a, T: 'static> LockAccess<std::sync::RwLock<T>, &'a mut T> for StdRwLockAccess<T> {
942    fn lock_read(&self, lock: &std::sync::RwLock<T>) -> Option<&'a mut T> {
943        lock.write().ok().map(|mut guard| {
944            let ptr = &mut *guard as *mut T;
945            unsafe { &mut *ptr }
946        })
947    }
948
949    fn lock_write(&self, lock: &std::sync::RwLock<T>) -> Option<&'a mut T> {
950        lock.write().ok().map(|mut guard| {
951            let ptr = &mut *guard as *mut T;
952            unsafe { &mut *ptr }
953        })
954    }
955}
956
957// ============================================================================
958// Parking Lot Mutex Access Implementation
959// ============================================================================
960// cargo test --lib --features "tokio,parking_lot" 2>&1 | grep -E "(test result|running)" | tail -5
961#[cfg(feature = "parking_lot")]
962/// Lock access implementation for Arc<parking_lot::Mutex<T>>
963///
964/// # Parking Lot Mutex
965///
966/// `parking_lot::Mutex` is a faster, more compact alternative to `std::sync::Mutex`:
967/// - **Smaller**: Only 1 byte of overhead vs std's platform-dependent size
968/// - **Faster**: More efficient locking algorithm
969/// - **No poisoning**: Unlike std::Mutex, doesn't panic on poisoned state
970/// - **Fair**: Implements a fair locking algorithm (FIFO)
971///
972/// # Cloning Behavior
973///
974/// This struct only contains `PhantomData<T>`.
975/// Cloning is a **zero-cost operation** - no data is copied.
976///
977/// # Performance
978///
979/// - **~2-3x faster** than std::Mutex in many scenarios
980/// - Better for high-contention workloads
981/// - More predictable latency due to fair scheduling
982///
983/// # When to Use
984///
985/// - High-contention scenarios where performance matters
986/// - When you want fair lock acquisition (no writer starvation)
987/// - When you don't need lock poisoning semantics
988#[derive(Clone)] // ZERO-COST: Only clones PhantomData (zero-sized type)
989pub struct ParkingLotMutexAccess<T> {
990    _phantom: std::marker::PhantomData<T>,
991}
992
993#[cfg(feature = "parking_lot")]
994impl<T> ParkingLotMutexAccess<T> {
995    pub fn new() -> Self {
996        Self {
997            _phantom: std::marker::PhantomData,
998        }
999    }
1000}
1001
1002#[cfg(feature = "parking_lot")]
1003impl<T> Default for ParkingLotMutexAccess<T> {
1004    fn default() -> Self {
1005        Self::new()
1006    }
1007}
1008
1009// Implementation for immutable access
1010#[cfg(feature = "parking_lot")]
1011impl<'a, T: 'static> LockAccess<Arc<parking_lot::Mutex<T>>, &'a T> for ParkingLotMutexAccess<T> {
1012    fn lock_read(&self, lock: &Arc<parking_lot::Mutex<T>>) -> Option<&'a T> {
1013        let guard = lock.lock();
1014        let ptr = &*guard as *const T;
1015        unsafe { Some(&*ptr) }
1016    }
1017
1018    fn lock_write(&self, lock: &Arc<parking_lot::Mutex<T>>) -> Option<&'a T> {
1019        let guard = lock.lock();
1020        let ptr = &*guard as *const T;
1021        unsafe { Some(&*ptr) }
1022    }
1023}
1024
1025// Implementation for mutable access
1026#[cfg(feature = "parking_lot")]
1027impl<'a, T: 'static> LockAccess<Arc<parking_lot::Mutex<T>>, &'a mut T>
1028    for ParkingLotMutexAccess<T>
1029{
1030    fn lock_read(&self, lock: &Arc<parking_lot::Mutex<T>>) -> Option<&'a mut T> {
1031        let mut guard = lock.lock();
1032        let ptr = &mut *guard as *mut T;
1033        unsafe { Some(&mut *ptr) }
1034    }
1035
1036    fn lock_write(&self, lock: &Arc<parking_lot::Mutex<T>>) -> Option<&'a mut T> {
1037        let mut guard = lock.lock();
1038        let ptr = &mut *guard as *mut T;
1039        unsafe { Some(&mut *ptr) }
1040    }
1041}
1042
1043// ============================================================================
1044// Parking Lot RwLock Access Implementation
1045// ============================================================================
1046
1047#[cfg(feature = "parking_lot")]
1048/// Lock access implementation for Arc<parking_lot::RwLock<T>>
1049///
1050/// # Parking Lot RwLock
1051///
1052/// `parking_lot::RwLock` is a faster alternative to `std::sync::RwLock`:
1053/// - **Smaller**: More compact memory representation
1054/// - **Faster**: More efficient locking and unlocking
1055/// - **No poisoning**: Unlike std::RwLock, doesn't panic on poisoned state
1056/// - **Writer-preferring**: Writers have priority to prevent writer starvation
1057/// - **Deadlock detection**: Optional deadlock detection in debug builds
1058///
1059/// # Cloning Behavior
1060///
1061/// This struct only contains `PhantomData<T>`.
1062/// Cloning is a **zero-cost operation** - no data is copied.
1063///
1064/// # Performance
1065///
1066/// - **Significantly faster** than std::RwLock for both read and write operations
1067/// - Better scalability with many readers
1068/// - Lower overhead per operation
1069///
1070/// # Writer Preference
1071///
1072/// Unlike std::RwLock which can starve writers, parking_lot's RwLock:
1073/// - Gives priority to writers when readers are present
1074/// - Prevents writer starvation in read-heavy workloads
1075/// - Still allows multiple concurrent readers when no writers are waiting
1076///
1077/// # When to Use
1078///
1079/// - Read-heavy workloads with occasional writes
1080/// - High-performance requirements
1081/// - When you need predictable writer scheduling
1082/// - When you don't need lock poisoning semantics
1083#[derive(Clone)] // ZERO-COST: Only clones PhantomData (zero-sized type)
1084pub struct ParkingLotRwLockAccess<T> {
1085    _phantom: std::marker::PhantomData<T>,
1086}
1087
1088#[cfg(feature = "parking_lot")]
1089impl<T> ParkingLotRwLockAccess<T> {
1090    pub fn new() -> Self {
1091        Self {
1092            _phantom: std::marker::PhantomData,
1093        }
1094    }
1095}
1096
1097#[cfg(feature = "parking_lot")]
1098impl<T> Default for ParkingLotRwLockAccess<T> {
1099    fn default() -> Self {
1100        Self::new()
1101    }
1102}
1103
1104// Implementation for immutable access (read lock)
1105#[cfg(feature = "parking_lot")]
1106impl<'a, T: 'static> LockAccess<Arc<parking_lot::RwLock<T>>, &'a T> for ParkingLotRwLockAccess<T> {
1107    fn lock_read(&self, lock: &Arc<parking_lot::RwLock<T>>) -> Option<&'a T> {
1108        let guard = lock.read();
1109        let ptr = &*guard as *const T;
1110        unsafe { Some(&*ptr) }
1111    }
1112
1113    fn lock_write(&self, lock: &Arc<parking_lot::RwLock<T>>) -> Option<&'a T> {
1114        // For immutable access, use read lock
1115        let guard = lock.read();
1116        let ptr = &*guard as *const T;
1117        unsafe { Some(&*ptr) }
1118    }
1119}
1120
1121// Implementation for mutable access (write lock)
1122#[cfg(feature = "parking_lot")]
1123impl<'a, T: 'static> LockAccess<Arc<parking_lot::RwLock<T>>, &'a mut T>
1124    for ParkingLotRwLockAccess<T>
1125{
1126    fn lock_read(&self, lock: &Arc<parking_lot::RwLock<T>>) -> Option<&'a mut T> {
1127        // For mutable access, use write lock
1128        let mut guard = lock.write();
1129        let ptr = &mut *guard as *mut T;
1130        unsafe { Some(&mut *ptr) }
1131    }
1132
1133    fn lock_write(&self, lock: &Arc<parking_lot::RwLock<T>>) -> Option<&'a mut T> {
1134        let mut guard = lock.write();
1135        let ptr = &mut *guard as *mut T;
1136        unsafe { Some(&mut *ptr) }
1137    }
1138}
1139
1140// ============================================================================
1141// Direct Parking Lot Mutex Access Implementation (without Arc)
1142// ============================================================================
1143
1144#[cfg(feature = "parking_lot")]
1145/// Lock access implementation for parking_lot::Mutex<T> (without Arc wrapper)
1146///
1147/// # Parking Lot Advantages
1148///
1149/// - Faster and more compact than std::sync::Mutex
1150/// - No lock poisoning
1151/// - Fair scheduling (FIFO)
1152///
1153/// # When to Use
1154///
1155/// Use this when you have a direct reference to a parking_lot::Mutex,
1156/// not wrapped in Arc.
1157#[derive(Clone)]
1158pub struct DirectParkingLotMutexAccess<T> {
1159    _phantom: std::marker::PhantomData<T>,
1160}
1161
1162#[cfg(feature = "parking_lot")]
1163impl<T> DirectParkingLotMutexAccess<T> {
1164    pub fn new() -> Self {
1165        Self {
1166            _phantom: std::marker::PhantomData,
1167        }
1168    }
1169}
1170
1171#[cfg(feature = "parking_lot")]
1172impl<T> Default for DirectParkingLotMutexAccess<T> {
1173    fn default() -> Self {
1174        Self::new()
1175    }
1176}
1177
1178#[cfg(feature = "parking_lot")]
1179impl<'a, T: 'static> LockAccess<parking_lot::Mutex<T>, &'a T> for DirectParkingLotMutexAccess<T> {
1180    fn lock_read(&self, lock: &parking_lot::Mutex<T>) -> Option<&'a T> {
1181        let guard = lock.lock();
1182        let ptr = &*guard as *const T;
1183        unsafe { Some(&*ptr) }
1184    }
1185
1186    fn lock_write(&self, lock: &parking_lot::Mutex<T>) -> Option<&'a T> {
1187        let guard = lock.lock();
1188        let ptr = &*guard as *const T;
1189        unsafe { Some(&*ptr) }
1190    }
1191}
1192
1193#[cfg(feature = "parking_lot")]
1194impl<'a, T: 'static> LockAccess<parking_lot::Mutex<T>, &'a mut T>
1195    for DirectParkingLotMutexAccess<T>
1196{
1197    fn lock_read(&self, lock: &parking_lot::Mutex<T>) -> Option<&'a mut T> {
1198        let mut guard = lock.lock();
1199        let ptr = &mut *guard as *mut T;
1200        unsafe { Some(&mut *ptr) }
1201    }
1202
1203    fn lock_write(&self, lock: &parking_lot::Mutex<T>) -> Option<&'a mut T> {
1204        let mut guard = lock.lock();
1205        let ptr = &mut *guard as *mut T;
1206        unsafe { Some(&mut *ptr) }
1207    }
1208}
1209
1210// ============================================================================
1211// Direct Parking Lot RwLock Access Implementation (without Arc)
1212// ============================================================================
1213
1214#[cfg(feature = "parking_lot")]
1215/// Lock access implementation for parking_lot::RwLock<T> (without Arc wrapper)
1216///
1217/// # Parking Lot RwLock Advantages
1218///
1219/// - Faster than std::sync::RwLock
1220/// - More compact memory footprint
1221/// - Fair scheduling
1222/// - Better for read-heavy workloads
1223///
1224/// # When to Use
1225///
1226/// Use this when you have a direct reference to a parking_lot::RwLock,
1227/// not wrapped in Arc.
1228#[derive(Clone)]
1229pub struct DirectParkingLotRwLockAccess<T> {
1230    _phantom: std::marker::PhantomData<T>,
1231}
1232
1233#[cfg(feature = "parking_lot")]
1234impl<T> DirectParkingLotRwLockAccess<T> {
1235    pub fn new() -> Self {
1236        Self {
1237            _phantom: std::marker::PhantomData,
1238        }
1239    }
1240}
1241
1242#[cfg(feature = "parking_lot")]
1243impl<T> Default for DirectParkingLotRwLockAccess<T> {
1244    fn default() -> Self {
1245        Self::new()
1246    }
1247}
1248
1249#[cfg(feature = "parking_lot")]
1250impl<'a, T: 'static> LockAccess<parking_lot::RwLock<T>, &'a T> for DirectParkingLotRwLockAccess<T> {
1251    fn lock_read(&self, lock: &parking_lot::RwLock<T>) -> Option<&'a T> {
1252        let guard = lock.read();
1253        let ptr = &*guard as *const T;
1254        unsafe { Some(&*ptr) }
1255    }
1256
1257    fn lock_write(&self, lock: &parking_lot::RwLock<T>) -> Option<&'a T> {
1258        let guard = lock.read();
1259        let ptr = &*guard as *const T;
1260        unsafe { Some(&*ptr) }
1261    }
1262}
1263
1264#[cfg(feature = "parking_lot")]
1265impl<'a, T: 'static> LockAccess<parking_lot::RwLock<T>, &'a mut T>
1266    for DirectParkingLotRwLockAccess<T>
1267{
1268    fn lock_read(&self, lock: &parking_lot::RwLock<T>) -> Option<&'a mut T> {
1269        let mut guard = lock.write();
1270        let ptr = &mut *guard as *mut T;
1271        unsafe { Some(&mut *ptr) }
1272    }
1273
1274    fn lock_write(&self, lock: &parking_lot::RwLock<T>) -> Option<&'a mut T> {
1275        let mut guard = lock.write();
1276        let ptr = &mut *guard as *mut T;
1277        unsafe { Some(&mut *ptr) }
1278    }
1279}
1280
1281// ============================================================================
1282// RefCell Access Implementation (Single-threaded)
1283// ============================================================================
1284
1285/// Lock access implementation for Rc<RefCell<T>>
1286///
1287/// # RefCell Semantics
1288///
1289/// `RefCell<T>` provides interior mutability with runtime borrow checking:
1290/// - Multiple immutable borrows are allowed simultaneously
1291/// - Only one mutable borrow is allowed at a time
1292/// - Borrows are checked at runtime (will panic if violated)
1293/// - **NOT thread-safe** - use only in single-threaded contexts
1294///
1295/// # Cloning Behavior
1296///
1297/// Like `ArcMutexAccess` and `ArcRwLockAccess`, this struct only contains `PhantomData<T>`.
1298/// Cloning is a **zero-cost operation** - no data is copied.
1299///
1300/// # Rc vs Arc
1301///
1302/// - **`Rc<RefCell<T>>`**: Single-threaded, lower overhead, no atomic operations
1303/// - **`Arc<Mutex<T>>`**: Multi-threaded, thread-safe, atomic reference counting
1304///
1305/// Use `RcRefCellAccess` when:
1306/// - Working in single-threaded context
1307/// - Want lower overhead than Arc/Mutex
1308/// - Don't need thread safety
1309///
1310/// # Example
1311///
1312/// ```ignore
1313/// use std::rc::Rc;
1314/// use std::cell::RefCell;
1315/// use rust_key_paths::lock::{LockKp, RcRefCellAccess};
1316/// use rust_key_paths::Kp;
1317///
1318/// #[derive(Clone)]
1319/// struct Root {
1320///     data: Rc<RefCell<Inner>>,
1321/// }
1322///
1323/// struct Inner {
1324///     value: String,
1325/// }
1326///
1327/// let lock_kp = LockKp::new(
1328///     Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data)),
1329///     RcRefCellAccess::new(),
1330///     Kp::new(|i: &Inner| Some(&i.value), |i: &mut Inner| Some(&mut i.value)),
1331/// );
1332/// ```
1333#[derive(Clone)] // ZERO-COST: Only clones PhantomData (zero-sized type)
1334pub struct RcRefCellAccess<T> {
1335    _phantom: std::marker::PhantomData<T>, // Zero-sized, no runtime cost
1336}
1337
1338impl<T> RcRefCellAccess<T> {
1339    pub fn new() -> Self {
1340        Self {
1341            _phantom: std::marker::PhantomData,
1342        }
1343    }
1344}
1345
1346impl<T> Default for RcRefCellAccess<T> {
1347    fn default() -> Self {
1348        Self::new()
1349    }
1350}
1351
1352// Implementation for immutable access (borrow)
1353impl<'a, T: 'static> LockAccess<std::rc::Rc<std::cell::RefCell<T>>, &'a T> for RcRefCellAccess<T> {
1354    fn lock_read(&self, lock: &std::rc::Rc<std::cell::RefCell<T>>) -> Option<&'a T> {
1355        // Acquire immutable borrow - allows multiple concurrent readers
1356        // SHALLOW CLONE: Only Rc refcount is incremented when accessing lock
1357        // Note: borrow() panics on borrow violation (not thread-safe, runtime check)
1358        let guard = lock.borrow();
1359        let ptr = &*guard as *const T;
1360        unsafe { Some(&*ptr) }
1361    }
1362
1363    fn lock_write(&self, lock: &std::rc::Rc<std::cell::RefCell<T>>) -> Option<&'a T> {
1364        // For immutable access, we use borrow (not borrow_mut)
1365        let guard = lock.borrow();
1366        let ptr = &*guard as *const T;
1367        unsafe { Some(&*ptr) }
1368    }
1369}
1370
1371// Implementation for mutable access (borrow_mut)
1372impl<'a, T: 'static> LockAccess<std::rc::Rc<std::cell::RefCell<T>>, &'a mut T>
1373    for RcRefCellAccess<T>
1374{
1375    fn lock_read(&self, lock: &std::rc::Rc<std::cell::RefCell<T>>) -> Option<&'a mut T> {
1376        // For mutable access, we need exclusive borrow
1377        // Note: borrow_mut() panics on borrow violation (not thread-safe, runtime check)
1378        let mut guard = lock.borrow_mut();
1379        let ptr = &mut *guard as *mut T;
1380        unsafe { Some(&mut *ptr) }
1381    }
1382
1383    fn lock_write(&self, lock: &std::rc::Rc<std::cell::RefCell<T>>) -> Option<&'a mut T> {
1384        // Acquire mutable borrow - exclusive access
1385        let mut guard = lock.borrow_mut();
1386        let ptr = &mut *guard as *mut T;
1387        unsafe { Some(&mut *ptr) }
1388    }
1389}
1390
1391// ============================================================================
1392// Helper Functions
1393// ============================================================================
1394
1395/// Type alias for LockKp over Arc<std::sync::Mutex<T>>. Use with derive macro's `_lock()` methods.
1396pub type LockKpArcMutexFor<Root, Lock, Inner> = LockKp<
1397    Root,
1398    Lock,
1399    Inner,
1400    Inner,
1401    &'static Root,
1402    &'static Lock,
1403    &'static Inner,
1404    &'static Inner,
1405    &'static mut Root,
1406    &'static mut Lock,
1407    &'static mut Inner,
1408    &'static mut Inner,
1409    for<'b> fn(&'b Root) -> Option<&'b Lock>,
1410    for<'b> fn(&'b mut Root) -> Option<&'b mut Lock>,
1411    ArcMutexAccess<Inner>,
1412    for<'b> fn(&'b Inner) -> Option<&'b Inner>,
1413    for<'b> fn(&'b mut Inner) -> Option<&'b mut Inner>,
1414>;
1415
1416/// Type alias for LockKp over Arc<std::sync::Mutex<Option<T>>>; value is T (extract from Option).
1417pub type LockKpArcMutexOptionFor<Root, Lock, Inner> = LockKp<
1418    Root,
1419    Lock,
1420    Option<Inner>,
1421    Inner,
1422    &'static Root,
1423    &'static Lock,
1424    &'static Option<Inner>,
1425    &'static Inner,
1426    &'static mut Root,
1427    &'static mut Lock,
1428    &'static mut Option<Inner>,
1429    &'static mut Inner,
1430    for<'b> fn(&'b Root) -> Option<&'b Lock>,
1431    for<'b> fn(&'b mut Root) -> Option<&'b mut Lock>,
1432    ArcMutexAccess<Option<Inner>>,
1433    for<'b> fn(&'b Option<Inner>) -> Option<&'b Inner>,
1434    for<'b> fn(&'b mut Option<Inner>) -> Option<&'b mut Inner>,
1435>;
1436
1437/// Type alias for LockKp over Arc<std::sync::RwLock<T>>. Use with derive macro's `_lock()` methods.
1438pub type LockKpArcRwLockFor<Root, Lock, Inner> = LockKp<
1439    Root,
1440    Lock,
1441    Inner,
1442    Inner,
1443    &'static Root,
1444    &'static Lock,
1445    &'static Inner,
1446    &'static Inner,
1447    &'static mut Root,
1448    &'static mut Lock,
1449    &'static mut Inner,
1450    &'static mut Inner,
1451    for<'b> fn(&'b Root) -> Option<&'b Lock>,
1452    for<'b> fn(&'b mut Root) -> Option<&'b mut Lock>,
1453    ArcRwLockAccess<Inner>,
1454    for<'b> fn(&'b Inner) -> Option<&'b Inner>,
1455    for<'b> fn(&'b mut Inner) -> Option<&'b mut Inner>,
1456>;
1457
1458/// Type alias for LockKp over Arc<std::sync::RwLock<Option<T>>>; value is T (extract from Option).
1459pub type LockKpArcRwLockOptionFor<Root, Lock, Inner> = LockKp<
1460    Root,
1461    Lock,
1462    Option<Inner>,
1463    Inner,
1464    &'static Root,
1465    &'static Lock,
1466    &'static Option<Inner>,
1467    &'static Inner,
1468    &'static mut Root,
1469    &'static mut Lock,
1470    &'static mut Option<Inner>,
1471    &'static mut Inner,
1472    for<'b> fn(&'b Root) -> Option<&'b Lock>,
1473    for<'b> fn(&'b mut Root) -> Option<&'b mut Lock>,
1474    ArcRwLockAccess<Option<Inner>>,
1475    for<'b> fn(&'b Option<Inner>) -> Option<&'b Inner>,
1476    for<'b> fn(&'b mut Option<Inner>) -> Option<&'b mut Inner>,
1477>;
1478
1479#[cfg(feature = "parking_lot")]
1480/// Type alias for LockKp over Arc<parking_lot::Mutex<T>>. Use with derive macro's `_lock()` methods.
1481pub type LockKpParkingLotMutexFor<Root, Lock, Inner> = LockKp<
1482    Root,
1483    Lock,
1484    Inner,
1485    Inner,
1486    &'static Root,
1487    &'static Lock,
1488    &'static Inner,
1489    &'static Inner,
1490    &'static mut Root,
1491    &'static mut Lock,
1492    &'static mut Inner,
1493    &'static mut Inner,
1494    for<'b> fn(&'b Root) -> Option<&'b Lock>,
1495    for<'b> fn(&'b mut Root) -> Option<&'b mut Lock>,
1496    ParkingLotMutexAccess<Inner>,
1497    for<'b> fn(&'b Inner) -> Option<&'b Inner>,
1498    for<'b> fn(&'b mut Inner) -> Option<&'b mut Inner>,
1499>;
1500
1501#[cfg(feature = "parking_lot")]
1502/// Type alias for LockKp over Arc<parking_lot::Mutex<Option<T>>>; value is T (extract from Option).
1503pub type LockKpParkingLotMutexOptionFor<Root, Lock, Inner> = LockKp<
1504    Root,
1505    Lock,
1506    Option<Inner>,
1507    Inner,
1508    &'static Root,
1509    &'static Lock,
1510    &'static Option<Inner>,
1511    &'static Inner,
1512    &'static mut Root,
1513    &'static mut Lock,
1514    &'static mut Option<Inner>,
1515    &'static mut Inner,
1516    for<'b> fn(&'b Root) -> Option<&'b Lock>,
1517    for<'b> fn(&'b mut Root) -> Option<&'b mut Lock>,
1518    ParkingLotMutexAccess<Option<Inner>>,
1519    for<'b> fn(&'b Option<Inner>) -> Option<&'b Inner>,
1520    for<'b> fn(&'b mut Option<Inner>) -> Option<&'b mut Inner>,
1521>;
1522
1523#[cfg(feature = "parking_lot")]
1524/// Type alias for LockKp over Arc<parking_lot::RwLock<T>>. Use with derive macro's `_lock()` methods.
1525pub type LockKpParkingLotRwLockFor<Root, Lock, Inner> = LockKp<
1526    Root,
1527    Lock,
1528    Inner,
1529    Inner,
1530    &'static Root,
1531    &'static Lock,
1532    &'static Inner,
1533    &'static Inner,
1534    &'static mut Root,
1535    &'static mut Lock,
1536    &'static mut Inner,
1537    &'static mut Inner,
1538    for<'b> fn(&'b Root) -> Option<&'b Lock>,
1539    for<'b> fn(&'b mut Root) -> Option<&'b mut Lock>,
1540    ParkingLotRwLockAccess<Inner>,
1541    for<'b> fn(&'b Inner) -> Option<&'b Inner>,
1542    for<'b> fn(&'b mut Inner) -> Option<&'b mut Inner>,
1543>;
1544
1545#[cfg(feature = "parking_lot")]
1546/// Type alias for LockKp over Arc<parking_lot::RwLock<Option<T>>>; value is T (extract from Option).
1547pub type LockKpParkingLotRwLockOptionFor<Root, Lock, Inner> = LockKp<
1548    Root,
1549    Lock,
1550    Option<Inner>,
1551    Inner,
1552    &'static Root,
1553    &'static Lock,
1554    &'static Option<Inner>,
1555    &'static Inner,
1556    &'static mut Root,
1557    &'static mut Lock,
1558    &'static mut Option<Inner>,
1559    &'static mut Inner,
1560    for<'b> fn(&'b Root) -> Option<&'b Lock>,
1561    for<'b> fn(&'b mut Root) -> Option<&'b mut Lock>,
1562    ParkingLotRwLockAccess<Option<Inner>>,
1563    for<'b> fn(&'b Option<Inner>) -> Option<&'b Inner>,
1564    for<'b> fn(&'b mut Option<Inner>) -> Option<&'b mut Inner>,
1565>;
1566
1567/// Type alias for common LockKp usage with Arc<Mutex<T>>
1568pub type LockKpType<'a, R, Mid, V> = LockKp<
1569    R,
1570    Arc<Mutex<Mid>>,
1571    Mid,
1572    V,
1573    &'a R,
1574    &'a Arc<Mutex<Mid>>,
1575    &'a Mid,
1576    &'a V,
1577    &'a mut R,
1578    &'a mut Arc<Mutex<Mid>>,
1579    &'a mut Mid,
1580    &'a mut V,
1581    for<'b> fn(&'b R) -> Option<&'b Arc<Mutex<Mid>>>,
1582    for<'b> fn(&'b mut R) -> Option<&'b mut Arc<Mutex<Mid>>>,
1583    ArcMutexAccess<Mid>,
1584    for<'b> fn(&'b Mid) -> Option<&'b V>,
1585    for<'b> fn(&'b mut Mid) -> Option<&'b mut V>,
1586>;
1587
1588#[cfg(test)]
1589mod tests {
1590    use super::*;
1591    use crate::KpType;
1592
1593    #[test]
1594    fn test_lock_kp_basic() {
1595        #[derive(Debug, Clone)]
1596        struct Root {
1597            locked_data: Arc<Mutex<Inner>>,
1598        }
1599
1600        #[derive(Debug, Clone)]
1601        struct Inner {
1602            value: String,
1603        }
1604
1605        let root = Root {
1606            locked_data: Arc::new(Mutex::new(Inner {
1607                value: "hello".to_string(),
1608            })),
1609        };
1610
1611        // Create prev keypath (Root -> Arc<Mutex<Inner>>)
1612        let prev_kp: KpType<Root, Arc<Mutex<Inner>>> = Kp::new(
1613            |r: &Root| Some(&r.locked_data),
1614            |r: &mut Root| Some(&mut r.locked_data),
1615        );
1616
1617        // Create next keypath (Inner -> String)
1618        let next_kp: KpType<Inner, String> = Kp::new(
1619            |i: &Inner| Some(&i.value),
1620            |i: &mut Inner| Some(&mut i.value),
1621        );
1622
1623        // Create lock keypath
1624        let lock_kp = LockKp::new(prev_kp, ArcMutexAccess::new(), next_kp);
1625
1626        // Test get
1627        let value = lock_kp.get(&root);
1628        assert!(value.is_some());
1629        // Note: Direct comparison may not work due to lifetime issues in this simple test
1630    }
1631
1632    #[test]
1633    fn test_lock_kp_get_optional_or_else() {
1634        #[derive(Debug, Clone)]
1635        struct Root {
1636            locked_data: Arc<Mutex<Inner>>,
1637        }
1638
1639        #[derive(Debug, Clone)]
1640        struct Inner {
1641            value: i32,
1642        }
1643
1644        let mut root = Root {
1645            locked_data: Arc::new(Mutex::new(Inner { value: 42 })),
1646        };
1647
1648        let prev_kp: KpType<Root, Arc<Mutex<Inner>>> = Kp::new(
1649            |r: &Root| Some(&r.locked_data),
1650            |r: &mut Root| Some(&mut r.locked_data),
1651        );
1652        let next_kp: KpType<Inner, i32> =
1653            Kp::new(|i: &Inner| Some(&i.value), |i: &mut Inner| Some(&mut i.value));
1654        let lock_kp = LockKp::new(prev_kp, ArcMutexAccess::new(), next_kp);
1655
1656        // get_optional
1657        assert!(lock_kp.get_optional(None).is_none());
1658        assert_eq!(lock_kp.get_optional(Some(&root)), Some(&42));
1659
1660        // get_mut_optional
1661        assert!(lock_kp.get_mut_optional(None).is_none());
1662        if let Some(m) = lock_kp.get_mut_optional(Some(&mut root)) {
1663            *m = 99;
1664        }
1665        assert_eq!(lock_kp.get(&root), Some(&99));
1666
1667        // get_or_else
1668        static DEFAULT: i32 = -1;
1669        let fallback = || &DEFAULT;
1670        assert_eq!(*lock_kp.get_or_else(None, fallback), -1);
1671        assert_eq!(*lock_kp.get_or_else(Some(&root), fallback), 99);
1672
1673        // get_mut_or_else: with Some we get the value; with None the fallback would be used (we only test Some here to avoid static mut)
1674        let m_some = lock_kp.get_mut_or_else(Some(&mut root), || panic!("should not use fallback"));
1675        *m_some = 100;
1676        assert_eq!(lock_kp.get(&root), Some(&100));
1677    }
1678
1679    #[test]
1680    fn test_kp_then_lock_kp_get_optional_or_else() {
1681        #[derive(Debug, Clone)]
1682        struct Root {
1683            data: Arc<Mutex<Mid>>,
1684        }
1685
1686        #[derive(Debug, Clone)]
1687        struct Mid {
1688            value: i32,
1689        }
1690
1691        let _root = Root {
1692            data: Arc::new(Mutex::new(Mid { value: 10 })),
1693        };
1694
1695        let prev: KpType<Root, Arc<Mutex<Mid>>> =
1696            Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
1697        let next: KpType<Mid, i32> =
1698            Kp::new(|m: &Mid| Some(&m.value), |m: &mut Mid| Some(&mut m.value));
1699        let lock_kp = LockKp::new(prev, ArcMutexAccess::new(), next);
1700
1701        assert!(lock_kp.get_optional(None).is_none());
1702        assert_eq!(lock_kp.get_optional(Some(&_root)), Some(&10));
1703
1704        static DEF: i32 = -1;
1705        assert_eq!(*lock_kp.get_or_else(None, || &DEF), -1);
1706        assert_eq!(*lock_kp.get_or_else(Some(&_root), || &DEF), 10);
1707    }
1708
1709    #[test]
1710    fn test_lock_kp_structure() {
1711        // This test verifies that the structure has the three required fields
1712        #[derive(Debug, Clone)]
1713        struct Root {
1714            data: Arc<Mutex<Mid>>,
1715        }
1716
1717        #[derive(Debug, Clone)]
1718        struct Mid {
1719            value: i32,
1720        }
1721
1722        let prev: KpType<Root, Arc<Mutex<Mid>>> =
1723            Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
1724
1725        let mid = ArcMutexAccess::<Mid>::new();
1726
1727        let next: KpType<Mid, i32> =
1728            Kp::new(|m: &Mid| Some(&m.value), |m: &mut Mid| Some(&mut m.value));
1729
1730        let lock_kp = LockKp::new(prev, mid, next);
1731
1732        // Verify the fields exist and are accessible
1733        let _prev_field = &lock_kp.prev;
1734        let _mid_field = &lock_kp.mid;
1735        let _next_field = &lock_kp.next;
1736    }
1737
1738    #[test]
1739    fn test_lock_kp_then_chaining() {
1740        #[derive(Debug, Clone)]
1741        struct Root {
1742            data: Arc<Mutex<Mid>>,
1743        }
1744
1745        #[derive(Debug, Clone)]
1746        struct Mid {
1747            inner: Inner2,
1748        }
1749
1750        #[derive(Debug, Clone)]
1751        struct Inner2 {
1752            value: String,
1753        }
1754
1755        let root = Root {
1756            data: Arc::new(Mutex::new(Mid {
1757                inner: Inner2 {
1758                    value: "chained".to_string(),
1759                },
1760            })),
1761        };
1762
1763        // Root -> Arc<Mutex<Mid>>
1764        let prev: KpType<Root, Arc<Mutex<Mid>>> =
1765            Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
1766
1767        // Mid -> Inner2
1768        let to_inner: KpType<Mid, Inner2> =
1769            Kp::new(|m: &Mid| Some(&m.inner), |m: &mut Mid| Some(&mut m.inner));
1770
1771        // Inner2 -> String
1772        let to_value: KpType<Inner2, String> = Kp::new(
1773            |i: &Inner2| Some(&i.value),
1774            |i: &mut Inner2| Some(&mut i.value),
1775        );
1776
1777        // Create initial lock keypath: Root -> Lock -> Mid -> Inner2
1778        let lock_kp = LockKp::new(prev, ArcMutexAccess::new(), to_inner);
1779
1780        // Chain with another keypath: Inner2 -> String
1781        let chained = lock_kp.then(to_value);
1782
1783        // The chained keypath should work
1784        // Note: Full functional test may require more complex setup due to lifetimes
1785        let _result = chained;
1786    }
1787
1788    #[test]
1789    fn test_lock_kp_compose_single_level() {
1790        // Test composing two single-level LockKps
1791        #[derive(Debug, Clone)]
1792        struct Root {
1793            data: Arc<Mutex<Mid1>>,
1794        }
1795
1796        #[derive(Debug, Clone)]
1797        struct Mid1 {
1798            nested: Arc<Mutex<Mid2>>,
1799        }
1800
1801        #[derive(Debug, Clone)]
1802        struct Mid2 {
1803            value: String,
1804        }
1805
1806        let root = Root {
1807            data: Arc::new(Mutex::new(Mid1 {
1808                nested: Arc::new(Mutex::new(Mid2 {
1809                    value: "nested-lock".to_string(),
1810                })),
1811            })),
1812        };
1813
1814        // First LockKp: Root -> Arc<Mutex<Mid1>> -> Mid1
1815        let lock_kp1 = {
1816            let prev: KpType<Root, Arc<Mutex<Mid1>>> =
1817                Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
1818            let next: KpType<Mid1, Mid1> = Kp::new(|m: &Mid1| Some(m), |m: &mut Mid1| Some(m));
1819            LockKp::new(prev, ArcMutexAccess::new(), next)
1820        };
1821
1822        // Second LockKp: Mid1 -> Arc<Mutex<Mid2>> -> String
1823        let lock_kp2 = {
1824            let prev: KpType<Mid1, Arc<Mutex<Mid2>>> = Kp::new(
1825                |m: &Mid1| Some(&m.nested),
1826                |m: &mut Mid1| Some(&mut m.nested),
1827            );
1828            let next: KpType<Mid2, String> =
1829                Kp::new(|m: &Mid2| Some(&m.value), |m: &mut Mid2| Some(&mut m.value));
1830            LockKp::new(prev, ArcMutexAccess::new(), next)
1831        };
1832
1833        // Compose them: Root -> Lock1 -> Mid1 -> Lock2 -> Mid2 -> String
1834        let composed = lock_kp1.then_lock(lock_kp2);
1835
1836        // Verify composition works
1837        let value = composed.get(&root);
1838        assert!(value.is_some());
1839    }
1840
1841    #[test]
1842    fn test_lock_kp_compose_two_levels() {
1843        // Test composing at two lock levels
1844        #[derive(Debug, Clone)]
1845        struct Root {
1846            level1: Arc<Mutex<Level1>>,
1847        }
1848
1849        #[derive(Debug, Clone)]
1850        struct Level1 {
1851            data: String,
1852            level2: Arc<Mutex<Level2>>,
1853        }
1854
1855        #[derive(Debug, Clone)]
1856        struct Level2 {
1857            value: i32,
1858        }
1859
1860        let root = Root {
1861            level1: Arc::new(Mutex::new(Level1 {
1862                data: "level1".to_string(),
1863                level2: Arc::new(Mutex::new(Level2 { value: 42 })),
1864            })),
1865        };
1866
1867        // First lock level
1868        let lock1 = {
1869            let prev: KpType<Root, Arc<Mutex<Level1>>> = Kp::new(
1870                |r: &Root| Some(&r.level1),
1871                |r: &mut Root| Some(&mut r.level1),
1872            );
1873            let next: KpType<Level1, Level1> =
1874                Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
1875            LockKp::new(prev, ArcMutexAccess::new(), next)
1876        };
1877
1878        // Second lock level
1879        let lock2 = {
1880            let prev: KpType<Level1, Arc<Mutex<Level2>>> = Kp::new(
1881                |l: &Level1| Some(&l.level2),
1882                |l: &mut Level1| Some(&mut l.level2),
1883            );
1884            let next: KpType<Level2, i32> = Kp::new(
1885                |l: &Level2| Some(&l.value),
1886                |l: &mut Level2| Some(&mut l.value),
1887            );
1888            LockKp::new(prev, ArcMutexAccess::new(), next)
1889        };
1890
1891        // Compose both locks
1892        let composed = lock1.then_lock(lock2);
1893
1894        // Test get
1895        let value = composed.get(&root);
1896        assert!(value.is_some());
1897    }
1898
1899    #[test]
1900    fn test_lock_kp_compose_three_levels() {
1901        // Test composing three lock levels
1902        #[derive(Debug, Clone)]
1903        struct Root {
1904            lock1: Arc<Mutex<L1>>,
1905        }
1906
1907        #[derive(Debug, Clone)]
1908        struct L1 {
1909            lock2: Arc<Mutex<L2>>,
1910        }
1911
1912        #[derive(Debug, Clone)]
1913        struct L2 {
1914            lock3: Arc<Mutex<L3>>,
1915        }
1916
1917        #[derive(Debug, Clone)]
1918        struct L3 {
1919            final_value: String,
1920        }
1921
1922        let root = Root {
1923            lock1: Arc::new(Mutex::new(L1 {
1924                lock2: Arc::new(Mutex::new(L2 {
1925                    lock3: Arc::new(Mutex::new(L3 {
1926                        final_value: "deeply-nested".to_string(),
1927                    })),
1928                })),
1929            })),
1930        };
1931
1932        // Lock level 1: Root -> L1
1933        let lock_kp1 = {
1934            let prev: KpType<Root, Arc<Mutex<L1>>> =
1935                Kp::new(|r: &Root| Some(&r.lock1), |r: &mut Root| Some(&mut r.lock1));
1936            let next: KpType<L1, L1> = Kp::new(|l: &L1| Some(l), |l: &mut L1| Some(l));
1937            LockKp::new(prev, ArcMutexAccess::new(), next)
1938        };
1939
1940        // Lock level 2: L1 -> L2
1941        let lock_kp2 = {
1942            let prev: KpType<L1, Arc<Mutex<L2>>> =
1943                Kp::new(|l: &L1| Some(&l.lock2), |l: &mut L1| Some(&mut l.lock2));
1944            let next: KpType<L2, L2> = Kp::new(|l: &L2| Some(l), |l: &mut L2| Some(l));
1945            LockKp::new(prev, ArcMutexAccess::new(), next)
1946        };
1947
1948        // Lock level 3: L2 -> L3 -> String
1949        let lock_kp3 = {
1950            let prev: KpType<L2, Arc<Mutex<L3>>> =
1951                Kp::new(|l: &L2| Some(&l.lock3), |l: &mut L2| Some(&mut l.lock3));
1952            let next: KpType<L3, String> = Kp::new(
1953                |l: &L3| Some(&l.final_value),
1954                |l: &mut L3| Some(&mut l.final_value),
1955            );
1956            LockKp::new(prev, ArcMutexAccess::new(), next)
1957        };
1958
1959        // Compose all three levels
1960        let composed_1_2 = lock_kp1.then_lock(lock_kp2);
1961        let composed_all = composed_1_2.then_lock(lock_kp3);
1962
1963        // Test get through all three lock levels
1964        let value = composed_all.get(&root);
1965        assert!(value.is_some());
1966    }
1967
1968    #[test]
1969    fn test_lock_kp_compose_with_then() {
1970        // Test combining compose and then
1971        #[derive(Debug, Clone)]
1972        struct Root {
1973            lock1: Arc<Mutex<Mid>>,
1974        }
1975
1976        #[derive(Debug, Clone)]
1977        struct Mid {
1978            lock2: Arc<Mutex<Inner>>,
1979        }
1980
1981        #[derive(Debug, Clone)]
1982        struct Inner {
1983            data: Data,
1984        }
1985
1986        #[derive(Debug, Clone)]
1987        struct Data {
1988            value: i32,
1989        }
1990
1991        let root = Root {
1992            lock1: Arc::new(Mutex::new(Mid {
1993                lock2: Arc::new(Mutex::new(Inner {
1994                    data: Data { value: 100 },
1995                })),
1996            })),
1997        };
1998
1999        // First lock
2000        let lock1 = {
2001            let prev: KpType<Root, Arc<Mutex<Mid>>> =
2002                Kp::new(|r: &Root| Some(&r.lock1), |r: &mut Root| Some(&mut r.lock1));
2003            let next: KpType<Mid, Mid> = Kp::new(|m: &Mid| Some(m), |m: &mut Mid| Some(m));
2004            LockKp::new(prev, ArcMutexAccess::new(), next)
2005        };
2006
2007        // Second lock
2008        let lock2 = {
2009            let prev: KpType<Mid, Arc<Mutex<Inner>>> =
2010                Kp::new(|m: &Mid| Some(&m.lock2), |m: &mut Mid| Some(&mut m.lock2));
2011            let next: KpType<Inner, Inner> = Kp::new(|i: &Inner| Some(i), |i: &mut Inner| Some(i));
2012            LockKp::new(prev, ArcMutexAccess::new(), next)
2013        };
2014
2015        // Regular keypath after locks
2016        let to_data: KpType<Inner, Data> =
2017            Kp::new(|i: &Inner| Some(&i.data), |i: &mut Inner| Some(&mut i.data));
2018
2019        let to_value: KpType<Data, i32> =
2020            Kp::new(|d: &Data| Some(&d.value), |d: &mut Data| Some(&mut d.value));
2021
2022        // Compose locks, then chain with regular keypaths
2023        let composed = lock1.then_lock(lock2);
2024        let with_data = composed.then(to_data);
2025        let with_value = with_data.then(to_value);
2026
2027        // Test get
2028        let value = with_value.get(&root);
2029        assert!(value.is_some());
2030    }
2031
2032    // ============================================================================
2033    // RwLock Tests
2034    // ============================================================================
2035
2036    #[test]
2037    fn test_rwlock_basic() {
2038        use std::sync::RwLock;
2039
2040        #[derive(Debug, Clone)]
2041        struct Root {
2042            data: Arc<RwLock<Inner>>,
2043        }
2044
2045        #[derive(Debug, Clone)]
2046        struct Inner {
2047            value: String,
2048        }
2049
2050        let root = Root {
2051            data: Arc::new(RwLock::new(Inner {
2052                value: "rwlock_value".to_string(),
2053            })),
2054        };
2055
2056        // Create RwLock keypath
2057        let prev: KpType<Root, Arc<RwLock<Inner>>> =
2058            Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2059
2060        let next: KpType<Inner, String> = Kp::new(
2061            |i: &Inner| Some(&i.value),
2062            |i: &mut Inner| Some(&mut i.value),
2063        );
2064
2065        let rwlock_kp = LockKp::new(prev, ArcRwLockAccess::new(), next);
2066
2067        // Test get (read lock)
2068        let value = rwlock_kp.get(&root);
2069        assert!(value.is_some());
2070    }
2071
2072    #[test]
2073    fn test_rwlock_compose_two_levels() {
2074        use std::sync::RwLock;
2075
2076        #[derive(Debug, Clone)]
2077        struct Root {
2078            level1: Arc<RwLock<Level1>>,
2079        }
2080
2081        #[derive(Debug, Clone)]
2082        struct Level1 {
2083            level2: Arc<RwLock<Level2>>,
2084        }
2085
2086        #[derive(Debug, Clone)]
2087        struct Level2 {
2088            value: i32,
2089        }
2090
2091        let root = Root {
2092            level1: Arc::new(RwLock::new(Level1 {
2093                level2: Arc::new(RwLock::new(Level2 { value: 100 })),
2094            })),
2095        };
2096
2097        // First RwLock level
2098        let lock1 = {
2099            let prev: KpType<Root, Arc<RwLock<Level1>>> = Kp::new(
2100                |r: &Root| Some(&r.level1),
2101                |r: &mut Root| Some(&mut r.level1),
2102            );
2103            let next: KpType<Level1, Level1> =
2104                Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
2105            LockKp::new(prev, ArcRwLockAccess::new(), next)
2106        };
2107
2108        // Second RwLock level
2109        let lock2 = {
2110            let prev: KpType<Level1, Arc<RwLock<Level2>>> = Kp::new(
2111                |l: &Level1| Some(&l.level2),
2112                |l: &mut Level1| Some(&mut l.level2),
2113            );
2114            let next: KpType<Level2, i32> = Kp::new(
2115                |l: &Level2| Some(&l.value),
2116                |l: &mut Level2| Some(&mut l.value),
2117            );
2118            LockKp::new(prev, ArcRwLockAccess::new(), next)
2119        };
2120
2121        // Compose both RwLocks
2122        let composed = lock1.then_lock(lock2);
2123
2124        // Test get through both read locks
2125        let value = composed.get(&root);
2126        assert!(value.is_some());
2127    }
2128
2129    #[test]
2130    fn test_rwlock_mixed_with_mutex() {
2131        use std::sync::RwLock;
2132
2133        #[derive(Debug, Clone)]
2134        struct Root {
2135            rwlock_data: Arc<RwLock<Mid>>,
2136        }
2137
2138        #[derive(Debug, Clone)]
2139        struct Mid {
2140            mutex_data: Arc<Mutex<Inner>>,
2141        }
2142
2143        #[derive(Debug, Clone)]
2144        struct Inner {
2145            value: String,
2146        }
2147
2148        let root = Root {
2149            rwlock_data: Arc::new(RwLock::new(Mid {
2150                mutex_data: Arc::new(Mutex::new(Inner {
2151                    value: "mixed".to_string(),
2152                })),
2153            })),
2154        };
2155
2156        // RwLock level
2157        let rwlock_kp = {
2158            let prev: KpType<Root, Arc<RwLock<Mid>>> = Kp::new(
2159                |r: &Root| Some(&r.rwlock_data),
2160                |r: &mut Root| Some(&mut r.rwlock_data),
2161            );
2162            let next: KpType<Mid, Mid> = Kp::new(|m: &Mid| Some(m), |m: &mut Mid| Some(m));
2163            LockKp::new(prev, ArcRwLockAccess::new(), next)
2164        };
2165
2166        // Mutex level
2167        let mutex_kp = {
2168            let prev: KpType<Mid, Arc<Mutex<Inner>>> = Kp::new(
2169                |m: &Mid| Some(&m.mutex_data),
2170                |m: &mut Mid| Some(&mut m.mutex_data),
2171            );
2172            let next: KpType<Inner, String> = Kp::new(
2173                |i: &Inner| Some(&i.value),
2174                |i: &mut Inner| Some(&mut i.value),
2175            );
2176            LockKp::new(prev, ArcMutexAccess::new(), next)
2177        };
2178
2179        // Compose RwLock -> Mutex
2180        let composed = rwlock_kp.then_lock(mutex_kp);
2181
2182        // Test get through both locks
2183        let value = composed.get(&root);
2184        assert!(value.is_some());
2185    }
2186
2187    #[test]
2188    fn test_rwlock_structure() {
2189        use std::sync::RwLock;
2190
2191        // Verify ArcRwLockAccess has the same zero-cost structure
2192        #[derive(Debug, Clone)]
2193        struct Root {
2194            data: Arc<RwLock<Inner>>,
2195        }
2196
2197        #[derive(Debug, Clone)]
2198        struct Inner {
2199            value: i32,
2200        }
2201
2202        let root = Root {
2203            data: Arc::new(RwLock::new(Inner { value: 42 })),
2204        };
2205
2206        let prev: KpType<Root, Arc<RwLock<Inner>>> =
2207            Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2208
2209        let mid = ArcRwLockAccess::<Inner>::new();
2210
2211        let next: KpType<Inner, i32> = Kp::new(
2212            |i: &Inner| Some(&i.value),
2213            |i: &mut Inner| Some(&mut i.value),
2214        );
2215
2216        let rwlock_kp = LockKp::new(prev, mid, next);
2217
2218        // Verify fields are accessible
2219        let _prev_field = &rwlock_kp.prev;
2220        let _mid_field = &rwlock_kp.mid;
2221        let _next_field = &rwlock_kp.next;
2222
2223        // Test basic get
2224        let value = rwlock_kp.get(&root);
2225        assert!(value.is_some());
2226    }
2227
2228    #[test]
2229    fn test_rwlock_three_levels() {
2230        use std::sync::RwLock;
2231
2232        #[derive(Debug, Clone)]
2233        struct Root {
2234            lock1: Arc<RwLock<L1>>,
2235        }
2236
2237        #[derive(Debug, Clone)]
2238        struct L1 {
2239            lock2: Arc<RwLock<L2>>,
2240        }
2241
2242        #[derive(Debug, Clone)]
2243        struct L2 {
2244            lock3: Arc<RwLock<L3>>,
2245        }
2246
2247        #[derive(Debug, Clone)]
2248        struct L3 {
2249            value: String,
2250        }
2251
2252        let root = Root {
2253            lock1: Arc::new(RwLock::new(L1 {
2254                lock2: Arc::new(RwLock::new(L2 {
2255                    lock3: Arc::new(RwLock::new(L3 {
2256                        value: "deep_rwlock".to_string(),
2257                    })),
2258                })),
2259            })),
2260        };
2261
2262        // Create three RwLock levels
2263        let lock1 = {
2264            let prev: KpType<Root, Arc<RwLock<L1>>> =
2265                Kp::new(|r: &Root| Some(&r.lock1), |r: &mut Root| Some(&mut r.lock1));
2266            let next: KpType<L1, L1> = Kp::new(|l: &L1| Some(l), |l: &mut L1| Some(l));
2267            LockKp::new(prev, ArcRwLockAccess::new(), next)
2268        };
2269
2270        let lock2 = {
2271            let prev: KpType<L1, Arc<RwLock<L2>>> =
2272                Kp::new(|l: &L1| Some(&l.lock2), |l: &mut L1| Some(&mut l.lock2));
2273            let next: KpType<L2, L2> = Kp::new(|l: &L2| Some(l), |l: &mut L2| Some(l));
2274            LockKp::new(prev, ArcRwLockAccess::new(), next)
2275        };
2276
2277        let lock3 = {
2278            let prev: KpType<L2, Arc<RwLock<L3>>> =
2279                Kp::new(|l: &L2| Some(&l.lock3), |l: &mut L2| Some(&mut l.lock3));
2280            let next: KpType<L3, String> =
2281                Kp::new(|l: &L3| Some(&l.value), |l: &mut L3| Some(&mut l.value));
2282            LockKp::new(prev, ArcRwLockAccess::new(), next)
2283        };
2284
2285        // Compose all three RwLocks
2286        let composed = lock1.then_lock(lock2).then_lock(lock3);
2287
2288        // Test get through all three read locks
2289        let value = composed.get(&root);
2290        assert!(value.is_some());
2291    }
2292
2293    #[test]
2294    fn test_rwlock_panic_on_clone_proof() {
2295        use std::sync::RwLock;
2296
2297        /// This struct PANICS if cloned - proving no deep cloning occurs
2298        struct PanicOnClone {
2299            data: String,
2300        }
2301
2302        impl PanicOnClone {
2303            fn new(s: &str) -> Self {
2304                Self {
2305                    data: s.to_string(),
2306                }
2307            }
2308
2309            fn get_data(&self) -> &String {
2310                &self.data
2311            }
2312        }
2313
2314        impl Clone for PanicOnClone {
2315            fn clone(&self) -> Self {
2316                panic!(
2317                    "❌ DEEP CLONE DETECTED! PanicOnClone was cloned! This should NEVER happen!"
2318                );
2319            }
2320        }
2321
2322        #[derive(Clone)]
2323        struct Root {
2324            lock1: Arc<RwLock<Level1>>,
2325        }
2326
2327        /// Level1 contains PanicOnClone - if it's cloned, test will panic
2328        struct Level1 {
2329            panic_data: PanicOnClone,
2330            lock2: Arc<RwLock<Level2>>,
2331        }
2332
2333        // We need Clone for Arc<RwLock<Level1>> to work, but we only clone the Arc
2334        impl Clone for Level1 {
2335            fn clone(&self) -> Self {
2336                // This should never be called during keypath operations
2337                // because Arc cloning doesn't clone the inner value
2338                panic!("❌ Level1 was deeply cloned! This should NEVER happen!");
2339            }
2340        }
2341
2342        /// Level2 also contains PanicOnClone
2343        struct Level2 {
2344            panic_data2: PanicOnClone,
2345            value: i32,
2346        }
2347
2348        impl Clone for Level2 {
2349            fn clone(&self) -> Self {
2350                panic!("❌ Level2 was deeply cloned! This should NEVER happen!");
2351            }
2352        }
2353
2354        // Create nested structure with PanicOnClone at each level
2355        let root = Root {
2356            lock1: Arc::new(RwLock::new(Level1 {
2357                panic_data: PanicOnClone::new("level1_data"),
2358                lock2: Arc::new(RwLock::new(Level2 {
2359                    panic_data2: PanicOnClone::new("level2_data"),
2360                    value: 42,
2361                })),
2362            })),
2363        };
2364
2365        // First RwLock level
2366        let lock1 = {
2367            let prev: KpType<Root, Arc<RwLock<Level1>>> =
2368                Kp::new(|r: &Root| Some(&r.lock1), |r: &mut Root| Some(&mut r.lock1));
2369            let next: KpType<Level1, Level1> =
2370                Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
2371            LockKp::new(prev, ArcRwLockAccess::new(), next)
2372        };
2373
2374        // Second RwLock level
2375        let lock2 = {
2376            let prev: KpType<Level1, Arc<RwLock<Level2>>> = Kp::new(
2377                |l: &Level1| Some(&l.lock2),
2378                |l: &mut Level1| Some(&mut l.lock2),
2379            );
2380            let next: KpType<Level2, i32> = Kp::new(
2381                |l: &Level2| Some(&l.value),
2382                |l: &mut Level2| Some(&mut l.value),
2383            );
2384            LockKp::new(prev, ArcRwLockAccess::new(), next)
2385        };
2386
2387        // CRITICAL TEST: Compose both locks
2388        // If any deep cloning occurs, the PanicOnClone will trigger and test will fail
2389        let composed = lock1.then_lock(lock2);
2390
2391        // If we get here without panic, shallow cloning is working correctly!
2392        // Now actually use the composed keypath
2393        let value = composed.get(&root);
2394
2395        // ✅ SUCCESS: No panic means no deep cloning occurred!
2396        // The Arc was cloned (shallow), but Level1, Level2, and PanicOnClone were NOT
2397        assert!(value.is_some());
2398    }
2399
2400    #[test]
2401    fn test_mutex_panic_on_clone_proof() {
2402        /// This struct PANICS if cloned - proving no deep cloning occurs
2403        struct PanicOnClone {
2404            data: Vec<u8>,
2405        }
2406
2407        impl PanicOnClone {
2408            fn new(size: usize) -> Self {
2409                Self {
2410                    data: vec![0u8; size],
2411                }
2412            }
2413        }
2414
2415        impl Clone for PanicOnClone {
2416            fn clone(&self) -> Self {
2417                panic!("❌ DEEP CLONE DETECTED! PanicOnClone was cloned!");
2418            }
2419        }
2420
2421        #[derive(Clone)]
2422        struct Root {
2423            lock1: Arc<Mutex<Mid>>,
2424        }
2425
2426        struct Mid {
2427            panic_data: PanicOnClone,
2428            lock2: Arc<Mutex<Inner>>,
2429        }
2430
2431        impl Clone for Mid {
2432            fn clone(&self) -> Self {
2433                panic!("❌ Mid was deeply cloned! This should NEVER happen!");
2434            }
2435        }
2436
2437        struct Inner {
2438            panic_data: PanicOnClone,
2439            value: String,
2440        }
2441
2442        impl Clone for Inner {
2443            fn clone(&self) -> Self {
2444                panic!("❌ Inner was deeply cloned! This should NEVER happen!");
2445            }
2446        }
2447
2448        // Create structure with PanicOnClone at each level
2449        let root = Root {
2450            lock1: Arc::new(Mutex::new(Mid {
2451                panic_data: PanicOnClone::new(1_000_000), // 1MB
2452                lock2: Arc::new(Mutex::new(Inner {
2453                    panic_data: PanicOnClone::new(1_000_000), // 1MB
2454                    value: "test".to_string(),
2455                })),
2456            })),
2457        };
2458
2459        // First Mutex level
2460        let lock1 = {
2461            let prev: KpType<Root, Arc<Mutex<Mid>>> =
2462                Kp::new(|r: &Root| Some(&r.lock1), |r: &mut Root| Some(&mut r.lock1));
2463            let next: KpType<Mid, Mid> = Kp::new(|m: &Mid| Some(m), |m: &mut Mid| Some(m));
2464            LockKp::new(prev, ArcMutexAccess::new(), next)
2465        };
2466
2467        // Second Mutex level
2468        let lock2 = {
2469            let prev: KpType<Mid, Arc<Mutex<Inner>>> =
2470                Kp::new(|m: &Mid| Some(&m.lock2), |m: &mut Mid| Some(&mut m.lock2));
2471            let next: KpType<Inner, String> = Kp::new(
2472                |i: &Inner| Some(&i.value),
2473                |i: &mut Inner| Some(&mut i.value),
2474            );
2475            LockKp::new(prev, ArcMutexAccess::new(), next)
2476        };
2477
2478        // CRITICAL TEST: Compose both Mutex locks
2479        // If any deep cloning occurs, PanicOnClone will trigger
2480        let composed = lock1.then_lock(lock2);
2481
2482        // ✅ SUCCESS: No panic means no deep cloning!
2483        let value = composed.get(&root);
2484        assert!(value.is_some());
2485    }
2486
2487    #[test]
2488    fn test_mixed_locks_panic_on_clone_proof() {
2489        use std::sync::RwLock;
2490
2491        /// Panic-on-clone struct for verification
2492        struct NeverClone {
2493            id: usize,
2494            large_data: Vec<u8>,
2495        }
2496
2497        impl NeverClone {
2498            fn new(id: usize) -> Self {
2499                Self {
2500                    id,
2501                    large_data: vec![0u8; 10_000],
2502                }
2503            }
2504        }
2505
2506        impl Clone for NeverClone {
2507            fn clone(&self) -> Self {
2508                panic!("❌ NeverClone with id {} was cloned!", self.id);
2509            }
2510        }
2511
2512        #[derive(Clone)]
2513        struct Root {
2514            rwlock: Arc<RwLock<Mid>>,
2515        }
2516
2517        struct Mid {
2518            never_clone1: NeverClone,
2519            mutex: Arc<Mutex<Inner>>,
2520        }
2521
2522        impl Clone for Mid {
2523            fn clone(&self) -> Self {
2524                panic!("❌ Mid was deeply cloned!");
2525            }
2526        }
2527
2528        struct Inner {
2529            never_clone2: NeverClone,
2530            value: i32,
2531        }
2532
2533        impl Clone for Inner {
2534            fn clone(&self) -> Self {
2535                panic!("❌ Inner was deeply cloned!");
2536            }
2537        }
2538
2539        // Create mixed RwLock -> Mutex structure
2540        let root = Root {
2541            rwlock: Arc::new(RwLock::new(Mid {
2542                never_clone1: NeverClone::new(1),
2543                mutex: Arc::new(Mutex::new(Inner {
2544                    never_clone2: NeverClone::new(2),
2545                    value: 999,
2546                })),
2547            })),
2548        };
2549
2550        // RwLock level
2551        let rwlock_kp = {
2552            let prev: KpType<Root, Arc<RwLock<Mid>>> = Kp::new(
2553                |r: &Root| Some(&r.rwlock),
2554                |r: &mut Root| Some(&mut r.rwlock),
2555            );
2556            let next: KpType<Mid, Mid> = Kp::new(|m: &Mid| Some(m), |m: &mut Mid| Some(m));
2557            LockKp::new(prev, ArcRwLockAccess::new(), next)
2558        };
2559
2560        // Mutex level
2561        let mutex_kp = {
2562            let prev: KpType<Mid, Arc<Mutex<Inner>>> =
2563                Kp::new(|m: &Mid| Some(&m.mutex), |m: &mut Mid| Some(&mut m.mutex));
2564            let next: KpType<Inner, i32> = Kp::new(
2565                |i: &Inner| Some(&i.value),
2566                |i: &mut Inner| Some(&mut i.value),
2567            );
2568            LockKp::new(prev, ArcMutexAccess::new(), next)
2569        };
2570
2571        // CRITICAL TEST: Compose RwLock with Mutex
2572        // If deep cloning occurs, NeverClone will panic
2573        let composed = rwlock_kp.then_lock(mutex_kp);
2574
2575        // ✅ SUCCESS: No panic = no deep cloning!
2576        // Only Arc refcounts were incremented
2577        let value = composed.get(&root);
2578        assert!(value.is_some());
2579
2580        // Additional verification: Use it multiple times
2581        let value2 = composed.get(&root);
2582        assert!(value2.is_some());
2583
2584        // Still no panic - proves shallow cloning is consistent
2585    }
2586
2587    // ========================================================================
2588    // Rc<RefCell<T>> Tests (Single-threaded)
2589    // ========================================================================
2590
2591    #[test]
2592    fn test_rc_refcell_basic() {
2593        use std::cell::RefCell;
2594        use std::rc::Rc;
2595
2596        #[derive(Clone)]
2597        struct Root {
2598            data: Rc<RefCell<Inner>>,
2599        }
2600
2601        #[derive(Clone)]
2602        struct Inner {
2603            value: String,
2604        }
2605
2606        let root = Root {
2607            data: Rc::new(RefCell::new(Inner {
2608                value: "hello".to_string(),
2609            })),
2610        };
2611
2612        // Create LockKp for Rc<RefCell<T>>
2613        let lock_kp = {
2614            let prev: KpType<Root, Rc<RefCell<Inner>>> =
2615                Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2616            let next: KpType<Inner, String> = Kp::new(
2617                |i: &Inner| Some(&i.value),
2618                |i: &mut Inner| Some(&mut i.value),
2619            );
2620            LockKp::new(prev, RcRefCellAccess::new(), next)
2621        };
2622
2623        // Test get
2624        let value = lock_kp.get(&root);
2625        assert!(value.is_some());
2626        assert_eq!(value.unwrap(), "hello");
2627
2628        // Test set
2629        let result = lock_kp.set(&root, |s| {
2630            *s = "world".to_string();
2631        });
2632        assert!(result.is_ok());
2633
2634        // Verify the change
2635        let value = lock_kp.get(&root);
2636        assert_eq!(value.unwrap(), "world");
2637    }
2638
2639    #[test]
2640    fn test_rc_refcell_compose_two_levels() {
2641        use std::cell::RefCell;
2642        use std::rc::Rc;
2643
2644        #[derive(Clone)]
2645        struct Root {
2646            level1: Rc<RefCell<Level1>>,
2647        }
2648
2649        #[derive(Clone)]
2650        struct Level1 {
2651            level2: Rc<RefCell<Level2>>,
2652        }
2653
2654        #[derive(Clone)]
2655        struct Level2 {
2656            value: i32,
2657        }
2658
2659        let root = Root {
2660            level1: Rc::new(RefCell::new(Level1 {
2661                level2: Rc::new(RefCell::new(Level2 { value: 42 })),
2662            })),
2663        };
2664
2665        // First level
2666        let lock1 = {
2667            let prev: KpType<Root, Rc<RefCell<Level1>>> = Kp::new(
2668                |r: &Root| Some(&r.level1),
2669                |r: &mut Root| Some(&mut r.level1),
2670            );
2671            let next: KpType<Level1, Level1> =
2672                Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
2673            LockKp::new(prev, RcRefCellAccess::new(), next)
2674        };
2675
2676        // Second level
2677        let lock2 = {
2678            let prev: KpType<Level1, Rc<RefCell<Level2>>> = Kp::new(
2679                |l: &Level1| Some(&l.level2),
2680                |l: &mut Level1| Some(&mut l.level2),
2681            );
2682            let next: KpType<Level2, i32> = Kp::new(
2683                |l: &Level2| Some(&l.value),
2684                |l: &mut Level2| Some(&mut l.value),
2685            );
2686            LockKp::new(prev, RcRefCellAccess::new(), next)
2687        };
2688
2689        // Compose both levels
2690        let composed = lock1.then_lock(lock2);
2691
2692        // Test get through both locks
2693        let value = composed.get(&root);
2694        assert!(value.is_some());
2695        assert_eq!(*value.unwrap(), 42);
2696
2697        // Test set through both locks
2698        let result = composed.set(&root, |v| {
2699            *v = 100;
2700        });
2701        assert!(result.is_ok());
2702
2703        // Verify change
2704        let value = composed.get(&root);
2705        assert_eq!(*value.unwrap(), 100);
2706    }
2707
2708    #[test]
2709    fn test_rc_refcell_three_levels() {
2710        use std::cell::RefCell;
2711        use std::rc::Rc;
2712
2713        #[derive(Clone)]
2714        struct Root {
2715            l1: Rc<RefCell<L1>>,
2716        }
2717
2718        #[derive(Clone)]
2719        struct L1 {
2720            l2: Rc<RefCell<L2>>,
2721        }
2722
2723        #[derive(Clone)]
2724        struct L2 {
2725            l3: Rc<RefCell<L3>>,
2726        }
2727
2728        #[derive(Clone)]
2729        struct L3 {
2730            value: String,
2731        }
2732
2733        let root = Root {
2734            l1: Rc::new(RefCell::new(L1 {
2735                l2: Rc::new(RefCell::new(L2 {
2736                    l3: Rc::new(RefCell::new(L3 {
2737                        value: "deep".to_string(),
2738                    })),
2739                })),
2740            })),
2741        };
2742
2743        // Level 1
2744        let lock1 = {
2745            let prev: KpType<Root, Rc<RefCell<L1>>> =
2746                Kp::new(|r: &Root| Some(&r.l1), |r: &mut Root| Some(&mut r.l1));
2747            let next: KpType<L1, L1> = Kp::new(|l: &L1| Some(l), |l: &mut L1| Some(l));
2748            LockKp::new(prev, RcRefCellAccess::new(), next)
2749        };
2750
2751        // Level 2
2752        let lock2 = {
2753            let prev: KpType<L1, Rc<RefCell<L2>>> =
2754                Kp::new(|l: &L1| Some(&l.l2), |l: &mut L1| Some(&mut l.l2));
2755            let next: KpType<L2, L2> = Kp::new(|l: &L2| Some(l), |l: &mut L2| Some(l));
2756            LockKp::new(prev, RcRefCellAccess::new(), next)
2757        };
2758
2759        // Level 3
2760        let lock3 = {
2761            let prev: KpType<L2, Rc<RefCell<L3>>> =
2762                Kp::new(|l: &L2| Some(&l.l3), |l: &mut L2| Some(&mut l.l3));
2763            let next: KpType<L3, String> =
2764                Kp::new(|l: &L3| Some(&l.value), |l: &mut L3| Some(&mut l.value));
2765            LockKp::new(prev, RcRefCellAccess::new(), next)
2766        };
2767
2768        // Compose all three levels
2769        let composed_1_2 = lock1.then_lock(lock2);
2770        let composed_all = composed_1_2.then_lock(lock3);
2771
2772        // Test get through all three locks
2773        let value = composed_all.get(&root);
2774        assert!(value.is_some());
2775        assert_eq!(value.unwrap(), "deep");
2776    }
2777
2778    #[test]
2779    fn test_rc_refcell_panic_on_clone_proof() {
2780        use std::cell::RefCell;
2781        use std::rc::Rc;
2782
2783        /// This struct PANICS if cloned - proving no deep cloning occurs
2784        struct PanicOnClone {
2785            data: String,
2786        }
2787
2788        impl Clone for PanicOnClone {
2789            fn clone(&self) -> Self {
2790                panic!("❌ DEEP CLONE DETECTED! PanicOnClone was cloned in Rc<RefCell>!");
2791            }
2792        }
2793
2794        #[derive(Clone)]
2795        struct Root {
2796            level1: Rc<RefCell<Level1>>,
2797        }
2798
2799        struct Level1 {
2800            panic_data: PanicOnClone,
2801            level2: Rc<RefCell<Level2>>,
2802        }
2803
2804        impl Clone for Level1 {
2805            fn clone(&self) -> Self {
2806                panic!("❌ Level1 was deeply cloned in Rc<RefCell>!");
2807            }
2808        }
2809
2810        struct Level2 {
2811            panic_data2: PanicOnClone,
2812            value: i32,
2813        }
2814
2815        impl Clone for Level2 {
2816            fn clone(&self) -> Self {
2817                panic!("❌ Level2 was deeply cloned in Rc<RefCell>!");
2818            }
2819        }
2820
2821        // Create nested Rc<RefCell> structure with PanicOnClone
2822        let root = Root {
2823            level1: Rc::new(RefCell::new(Level1 {
2824                panic_data: PanicOnClone {
2825                    data: "level1".to_string(),
2826                },
2827                level2: Rc::new(RefCell::new(Level2 {
2828                    panic_data2: PanicOnClone {
2829                        data: "level2".to_string(),
2830                    },
2831                    value: 123,
2832                })),
2833            })),
2834        };
2835
2836        // First level
2837        let lock1 = {
2838            let prev: KpType<Root, Rc<RefCell<Level1>>> = Kp::new(
2839                |r: &Root| Some(&r.level1),
2840                |r: &mut Root| Some(&mut r.level1),
2841            );
2842            let next: KpType<Level1, Level1> =
2843                Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
2844            LockKp::new(prev, RcRefCellAccess::new(), next)
2845        };
2846
2847        // Second level
2848        let lock2 = {
2849            let prev: KpType<Level1, Rc<RefCell<Level2>>> = Kp::new(
2850                |l: &Level1| Some(&l.level2),
2851                |l: &mut Level1| Some(&mut l.level2),
2852            );
2853            let next: KpType<Level2, i32> = Kp::new(
2854                |l: &Level2| Some(&l.value),
2855                |l: &mut Level2| Some(&mut l.value),
2856            );
2857            LockKp::new(prev, RcRefCellAccess::new(), next)
2858        };
2859
2860        // CRITICAL TEST: Compose both Rc<RefCell> locks
2861        // If any deep cloning occurs, PanicOnClone will trigger
2862        let composed = lock1.then_lock(lock2);
2863
2864        // ✅ SUCCESS: No panic means no deep cloning!
2865        // Only Rc refcounts were incremented (shallow)
2866        let value = composed.get(&root);
2867        assert!(value.is_some());
2868        assert_eq!(*value.unwrap(), 123);
2869
2870        // Additional test: Multiple accesses don't clone
2871        let value2 = composed.get(&root);
2872        assert!(value2.is_some());
2873    }
2874
2875    #[test]
2876    fn test_rc_refcell_vs_arc_mutex() {
2877        use std::cell::RefCell;
2878        use std::rc::Rc;
2879
2880        // This test demonstrates the API similarity between Rc<RefCell> and Arc<Mutex>
2881
2882        #[derive(Clone)]
2883        struct RcRoot {
2884            data: Rc<RefCell<String>>,
2885        }
2886
2887        #[derive(Clone)]
2888        struct ArcRoot {
2889            data: Arc<Mutex<String>>,
2890        }
2891
2892        // Rc<RefCell> version (single-threaded)
2893        let rc_root = RcRoot {
2894            data: Rc::new(RefCell::new("rc_value".to_string())),
2895        };
2896
2897        let rc_kp = {
2898            let prev: KpType<RcRoot, Rc<RefCell<String>>> = Kp::new(
2899                |r: &RcRoot| Some(&r.data),
2900                |r: &mut RcRoot| Some(&mut r.data),
2901            );
2902            let next: KpType<String, String> =
2903                Kp::new(|s: &String| Some(s), |s: &mut String| Some(s));
2904            LockKp::new(prev, RcRefCellAccess::new(), next)
2905        };
2906
2907        // Arc<Mutex> version (multi-threaded)
2908        let arc_root = ArcRoot {
2909            data: Arc::new(Mutex::new("arc_value".to_string())),
2910        };
2911
2912        let arc_kp = {
2913            let prev: KpType<ArcRoot, Arc<Mutex<String>>> = Kp::new(
2914                |r: &ArcRoot| Some(&r.data),
2915                |r: &mut ArcRoot| Some(&mut r.data),
2916            );
2917            let next: KpType<String, String> =
2918                Kp::new(|s: &String| Some(s), |s: &mut String| Some(s));
2919            LockKp::new(prev, ArcMutexAccess::new(), next)
2920        };
2921
2922        // Both have identical API usage!
2923        let rc_value = rc_kp.get(&rc_root);
2924        let arc_value = arc_kp.get(&arc_root);
2925
2926        assert_eq!(rc_value.unwrap(), "rc_value");
2927        assert_eq!(arc_value.unwrap(), "arc_value");
2928    }
2929
2930    // ========================================================================
2931    // Parking Lot Tests
2932    // ========================================================================
2933
2934    #[cfg(feature = "parking_lot")]
2935    #[test]
2936    fn test_parking_lot_mutex_basic() {
2937        use parking_lot::Mutex;
2938
2939        #[derive(Clone)]
2940        struct Root {
2941            data: Arc<Mutex<String>>,
2942        }
2943
2944        let root = Root {
2945            data: Arc::new(Mutex::new("parking_lot_mutex".to_string())),
2946        };
2947
2948        let lock_kp = {
2949            let prev: KpType<Root, Arc<Mutex<String>>> =
2950                Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2951            let next: KpType<String, String> =
2952                Kp::new(|s: &String| Some(s), |s: &mut String| Some(s));
2953            LockKp::new(prev, ParkingLotMutexAccess::new(), next)
2954        };
2955
2956        let value = lock_kp.get(&root);
2957        assert_eq!(value.unwrap(), &"parking_lot_mutex".to_string());
2958    }
2959
2960    #[cfg(feature = "parking_lot")]
2961    #[test]
2962    fn test_parking_lot_rwlock_basic() {
2963        use parking_lot::RwLock;
2964
2965        #[derive(Clone)]
2966        struct Root {
2967            data: Arc<RwLock<Vec<i32>>>,
2968        }
2969
2970        let root = Root {
2971            data: Arc::new(RwLock::new(vec![1, 2, 3, 4, 5])),
2972        };
2973
2974        let lock_kp = {
2975            let prev: KpType<Root, Arc<RwLock<Vec<i32>>>> =
2976                Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
2977            let next: KpType<Vec<i32>, Vec<i32>> =
2978                Kp::new(|v: &Vec<i32>| Some(v), |v: &mut Vec<i32>| Some(v));
2979            LockKp::new(prev, ParkingLotRwLockAccess::new(), next)
2980        };
2981
2982        let value = lock_kp.get(&root);
2983        assert_eq!(value.unwrap().len(), 5);
2984        assert_eq!(value.unwrap()[2], 3);
2985    }
2986
2987    #[cfg(feature = "parking_lot")]
2988    #[test]
2989    fn test_parking_lot_mutex_compose() {
2990        use parking_lot::Mutex;
2991
2992        #[derive(Clone)]
2993        struct Root {
2994            level1: Arc<Mutex<Level1>>,
2995        }
2996
2997        #[derive(Clone)]
2998        struct Level1 {
2999            level2: Arc<Mutex<i32>>,
3000        }
3001
3002        let root = Root {
3003            level1: Arc::new(Mutex::new(Level1 {
3004                level2: Arc::new(Mutex::new(42)),
3005            })),
3006        };
3007
3008        // First level: Root -> Level1
3009        let lock1 = {
3010            let prev: KpType<Root, Arc<Mutex<Level1>>> = Kp::new(
3011                |r: &Root| Some(&r.level1),
3012                |r: &mut Root| Some(&mut r.level1),
3013            );
3014            let next: KpType<Level1, Level1> =
3015                Kp::new(|l: &Level1| Some(l), |l: &mut Level1| Some(l));
3016            LockKp::new(prev, ParkingLotMutexAccess::new(), next)
3017        };
3018
3019        // Second level: Level1 -> i32
3020        let lock2 = {
3021            let prev: KpType<Level1, Arc<Mutex<i32>>> = Kp::new(
3022                |l: &Level1| Some(&l.level2),
3023                |l: &mut Level1| Some(&mut l.level2),
3024            );
3025            let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
3026            LockKp::new(prev, ParkingLotMutexAccess::new(), next)
3027        };
3028
3029        // Compose both levels
3030        let composed = lock1.then_lock(lock2);
3031        let value = composed.get(&root);
3032        assert_eq!(value.unwrap(), &42);
3033    }
3034
3035    #[cfg(feature = "parking_lot")]
3036    #[test]
3037    fn test_parking_lot_rwlock_write() {
3038        use parking_lot::RwLock;
3039
3040        #[derive(Clone)]
3041        struct Root {
3042            data: Arc<RwLock<i32>>,
3043        }
3044
3045        let mut root = Root {
3046            data: Arc::new(RwLock::new(100)),
3047        };
3048
3049        let lock_kp = {
3050            let prev: KpType<Root, Arc<RwLock<i32>>> =
3051                Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3052            let next: KpType<i32, i32> = Kp::new(|n: &i32| Some(n), |n: &mut i32| Some(n));
3053            LockKp::new(prev, ParkingLotRwLockAccess::new(), next)
3054        };
3055
3056        // Read initial value
3057        let value = lock_kp.get(&root);
3058        assert_eq!(value.unwrap(), &100);
3059
3060        // Get mutable access and modify
3061        let mut_value = lock_kp.get_mut(&mut root);
3062        assert!(mut_value.is_some());
3063        if let Some(v) = mut_value {
3064            *v = 200;
3065        }
3066
3067        // Verify the change
3068        let new_value = lock_kp.get(&root);
3069        assert_eq!(new_value.unwrap(), &200);
3070    }
3071
3072    #[cfg(feature = "parking_lot")]
3073    #[test]
3074    fn test_parking_lot_panic_on_clone_proof() {
3075        use parking_lot::Mutex;
3076
3077        /// This struct PANICS if cloned - proving no deep cloning occurs
3078        struct PanicOnClone {
3079            data: String,
3080        }
3081
3082        impl Clone for PanicOnClone {
3083            fn clone(&self) -> Self {
3084                panic!("❌ PARKING_LOT DEEP CLONE DETECTED! PanicOnClone was cloned!");
3085            }
3086        }
3087
3088        #[derive(Clone)]
3089        struct Root {
3090            level1: Arc<Mutex<Level1>>,
3091        }
3092
3093        struct Level1 {
3094            panic_data: PanicOnClone,
3095            value: i32,
3096        }
3097
3098        impl Clone for Level1 {
3099            fn clone(&self) -> Self {
3100                panic!("❌ Level1 was deeply cloned in parking_lot context!");
3101            }
3102        }
3103
3104        let root = Root {
3105            level1: Arc::new(Mutex::new(Level1 {
3106                panic_data: PanicOnClone {
3107                    data: "test".to_string(),
3108                },
3109                value: 123,
3110            })),
3111        };
3112
3113        let lock_kp = {
3114            let prev: KpType<Root, Arc<Mutex<Level1>>> = Kp::new(
3115                |r: &Root| Some(&r.level1),
3116                |r: &mut Root| Some(&mut r.level1),
3117            );
3118            let next: KpType<Level1, i32> = Kp::new(
3119                |l: &Level1| Some(&l.value),
3120                |l: &mut Level1| Some(&mut l.value),
3121            );
3122            LockKp::new(prev, ParkingLotMutexAccess::new(), next)
3123        };
3124
3125        // CRITICAL TEST: If any deep cloning occurs, PanicOnClone will trigger
3126        let value = lock_kp.get(&root);
3127
3128        // ✅ SUCCESS: No panic means no deep cloning!
3129        assert_eq!(value.unwrap(), &123);
3130    }
3131
3132    #[test]
3133    fn test_std_mutex_direct() {
3134        use std::sync::Mutex;
3135
3136        struct Root {
3137            data: Mutex<Inner>,
3138        }
3139
3140        struct Inner {
3141            value: i32,
3142        }
3143
3144        let mut root = Root {
3145            data: Mutex::new(Inner { value: 42 }),
3146        };
3147
3148        let lock_kp = {
3149            let prev: KpType<Root, Mutex<Inner>> =
3150                Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3151            let next: KpType<Inner, i32> = Kp::new(
3152                |i: &Inner| Some(&i.value),
3153                |i: &mut Inner| Some(&mut i.value),
3154            );
3155            LockKp::new(prev, StdMutexAccess::new(), next)
3156        };
3157
3158        // Test read access
3159        let value = lock_kp.get(&root);
3160        assert_eq!(value, Some(&42));
3161
3162        // Test write access
3163        lock_kp.get_mut(&mut root).map(|v| *v = 100);
3164        let value = lock_kp.get(&root);
3165        assert_eq!(value, Some(&100));
3166    }
3167
3168    #[test]
3169    fn test_std_rwlock_direct() {
3170        use std::sync::RwLock;
3171
3172        struct Root {
3173            data: RwLock<Inner>,
3174        }
3175
3176        struct Inner {
3177            value: String,
3178        }
3179
3180        let mut root = Root {
3181            data: RwLock::new(Inner {
3182                value: "hello".to_string(),
3183            }),
3184        };
3185
3186        let lock_kp = {
3187            let prev: KpType<Root, RwLock<Inner>> =
3188                Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3189            let next: KpType<Inner, String> = Kp::new(
3190                |i: &Inner| Some(&i.value),
3191                |i: &mut Inner| Some(&mut i.value),
3192            );
3193            LockKp::new(prev, StdRwLockAccess::new(), next)
3194        };
3195
3196        // Test read access
3197        let value = lock_kp.get(&root);
3198        assert_eq!(value.as_ref().map(|s| s.as_str()), Some("hello"));
3199
3200        // Test write access
3201        lock_kp.get_mut(&mut root).map(|v| *v = "world".to_string());
3202        let value = lock_kp.get(&root);
3203        assert_eq!(value.as_ref().map(|s| s.as_str()), Some("world"));
3204    }
3205
3206    #[cfg(feature = "parking_lot")]
3207    #[test]
3208    fn test_parking_lot_mutex_direct() {
3209        use parking_lot::Mutex;
3210
3211        struct Root {
3212            data: Mutex<Inner>,
3213        }
3214
3215        struct Inner {
3216            value: i32,
3217        }
3218
3219        let mut root = Root {
3220            data: Mutex::new(Inner { value: 42 }),
3221        };
3222
3223        let lock_kp = {
3224            let prev: KpType<Root, Mutex<Inner>> =
3225                Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3226            let next: KpType<Inner, i32> = Kp::new(
3227                |i: &Inner| Some(&i.value),
3228                |i: &mut Inner| Some(&mut i.value),
3229            );
3230            LockKp::new(prev, DirectParkingLotMutexAccess::new(), next)
3231        };
3232
3233        // Test read access
3234        let value = lock_kp.get(&root);
3235        assert_eq!(value, Some(&42));
3236
3237        // Test write access
3238        lock_kp.get_mut(&mut root).map(|v| *v = 100);
3239        let value = lock_kp.get(&root);
3240        assert_eq!(value, Some(&100));
3241    }
3242
3243    #[cfg(feature = "parking_lot")]
3244    #[test]
3245    fn test_parking_lot_rwlock_direct() {
3246        use parking_lot::RwLock;
3247
3248        struct Root {
3249            data: RwLock<Inner>,
3250        }
3251
3252        struct Inner {
3253            value: String,
3254        }
3255
3256        let mut root = Root {
3257            data: RwLock::new(Inner {
3258                value: "hello".to_string(),
3259            }),
3260        };
3261
3262        let lock_kp = {
3263            let prev: KpType<Root, RwLock<Inner>> =
3264                Kp::new(|r: &Root| Some(&r.data), |r: &mut Root| Some(&mut r.data));
3265            let next: KpType<Inner, String> = Kp::new(
3266                |i: &Inner| Some(&i.value),
3267                |i: &mut Inner| Some(&mut i.value),
3268            );
3269            LockKp::new(prev, DirectParkingLotRwLockAccess::new(), next)
3270        };
3271
3272        // Test read access
3273        let value = lock_kp.get(&root);
3274        assert_eq!(value.as_ref().map(|s| s.as_str()), Some("hello"));
3275
3276        // Test write access
3277        lock_kp.get_mut(&mut root).map(|v| *v = "world".to_string());
3278        let value = lock_kp.get(&root);
3279        assert_eq!(value.as_ref().map(|s| s.as_str()), Some("world"));
3280    }
3281}