Skip to main content

rust_key_paths/
lock.rs

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