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