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