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