Skip to main content

rust_key_paths/
sync_kp.rs

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