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