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