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