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