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