Skip to main content

LockKp

Struct LockKp 

Source
pub struct LockKp<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2>
where Root: Borrow<R>, LockValue: Borrow<Lock>, MidValue: Borrow<Mid>, Value: Borrow<V>, MutRoot: BorrowMut<R>, MutLock: BorrowMut<Lock>, MutMid: BorrowMut<Mid>, MutValue: BorrowMut<V>, G1: Fn(Root) -> Option<LockValue>, S1: Fn(MutRoot) -> Option<MutLock>, L: LockAccess<Lock, MidValue> + LockAccess<Lock, MutMid>, G2: Fn(MidValue) -> Option<Value>, S2: Fn(MutMid) -> Option<MutValue>,
{ pub prev: Kp<R, Lock, Root, LockValue, MutRoot, MutLock, G1, S1>, pub mid: L, pub next: Kp<Mid, V, MidValue, Value, MutMid, MutValue, G2, S2>, }
Expand description

A keypath that handles locked values (e.g., Arc<Mutex>)

Structure:

  • prev: Keypath from Root to Lock container (e.g., Arc<Mutex>)
  • mid: Lock access handler that goes from Lock to Inner value
  • next: Keypath from Inner value to final Value

§Type Parameters

  • R: Root type (base)
  • Lock: Lock container type (e.g., Arc<Mutex>)
  • Mid: The type inside the lock
  • V: Final value type
  • Rest are the same generic parameters as Kp

§Cloning Behavior

IMPORTANT: All Clone operations in this struct are SHALLOW clones:

  • LockKp itself derives Clone - this clones the three field references/closures
  • prev and next fields are Kp structs containing function pointers (cheap to clone)
  • mid field implements LockAccess trait - typically just PhantomData (zero-cost clone)
  • NO Lock: Clone needed for lock operations - we use &Lock directly via interior mutability
  • NO deep data cloning occurs - all clones are pointer/reference copies

§Example

use std::sync::{Arc, Mutex};

struct Root {
    data: Arc<Mutex<Inner>>,
}

struct Inner {
    value: String,
}

// Create a LockKp that goes: Root -> Arc<Mutex<Inner>> -> String
let lock_kp = LockKp::new(
    root_to_lock_kp,
    ArcMutexAccess::new(),
    inner_to_value_kp,
);

Fields§

§prev: Kp<R, Lock, Root, LockValue, MutRoot, MutLock, G1, S1>

Keypath from Root to Lock container

§mid: L

Lock access handler (converts Lock -> Inner)

§next: Kp<Mid, V, MidValue, Value, MutMid, MutValue, G2, S2>

Keypath from Inner to final Value

Implementations§

Source§

impl<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2> LockKp<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2>
where Root: Borrow<R>, LockValue: Borrow<Lock>, MidValue: Borrow<Mid>, Value: Borrow<V>, MutRoot: BorrowMut<R>, MutLock: BorrowMut<Lock>, MutMid: BorrowMut<Mid>, MutValue: BorrowMut<V>, G1: Fn(Root) -> Option<LockValue>, S1: Fn(MutRoot) -> Option<MutLock>, L: LockAccess<Lock, MidValue> + LockAccess<Lock, MutMid>, G2: Fn(MidValue) -> Option<Value>, S2: Fn(MutMid) -> Option<MutValue>,

Source

pub fn new( prev: Kp<R, Lock, Root, LockValue, MutRoot, MutLock, G1, S1>, mid: L, next: Kp<Mid, V, MidValue, Value, MutMid, MutValue, G2, S2>, ) -> Self

Create a new LockKp with prev, mid, and next components

Source

pub fn get(&self, root: Root) -> Option<Value>
where V: Clone,

Get the value through the lock

This will:

  1. Use prev to get to the Lock
  2. Use mid to lock and get Inner value
  3. Use next to get from Inner to final Value

Get an immutable reference through the lock.

§Cloning Behavior

Only requires V: Clone for the final value. NO Lock: Clone needed because lock_read takes &Lock.

Source

pub fn get_mut(&self, root: MutRoot) -> Option<MutValue>

Get mutable access to the value through the lock

§NO CLONING Required!

No longer needs Lock: Clone because lock_write now takes &Lock instead of &mut Lock

Source

pub fn set<F>(&self, root: Root, updater: F) -> Result<(), String>
where F: FnOnce(&mut V), MutValue: BorrowMut<V>,

Set the value through the lock using an updater function

§NO CLONING Required!

Unlike the original implementation, we NO LONGER need Lock: Clone because:

  • Locks like Mutex and RwLock provide interior mutability
  • We only need &Lock, not &mut Lock, to get mutable access to the inner data
  • This eliminates an unnecessary Arc reference count increment
Source

pub fn then<V2, Value2, MutValue2, G3, S3>( self, next_kp: Kp<V, V2, Value, Value2, MutValue, MutValue2, G3, S3>, ) -> LockKp<R, Lock, Mid, V2, Root, LockValue, MidValue, Value2, MutRoot, MutLock, MutMid, MutValue2, G1, S1, L, impl Fn(MidValue) -> Option<Value2>, impl Fn(MutMid) -> Option<MutValue2>>
where V: 'static, V2: 'static, Value: Borrow<V>, Value2: Borrow<V2>, MutValue: BorrowMut<V>, MutValue2: BorrowMut<V2>, G3: Fn(Value) -> Option<Value2> + 'static, S3: Fn(MutValue) -> Option<MutValue2> + 'static,

Chain this LockKp with another regular Kp

This allows you to continue navigating after getting through the lock: Root -> Lock -> Mid -> Value1 -> Value2

§Cloning Behavior

No cloning occurs in this method - closures are moved into the new Kp

Source

pub fn then_lock<Lock2, Mid2, V2, LockValue2, MidValue2, Value2, MutLock2, MutMid2, MutValue2, G2_1, S2_1, L2, G2_2, S2_2>( self, other: LockKp<V, Lock2, Mid2, V2, Value, LockValue2, MidValue2, Value2, MutValue, MutLock2, MutMid2, MutValue2, G2_1, S2_1, L2, G2_2, S2_2>, ) -> LockKp<R, Lock, Mid, V2, Root, LockValue, MidValue, Value2, MutRoot, MutLock, MutMid, MutValue2, G1, S1, L, impl Fn(MidValue) -> Option<Value2>, impl Fn(MutMid) -> Option<MutValue2>>
where V: 'static + Clone, V2: 'static, Lock2: Clone, Value: Borrow<V>, LockValue2: Borrow<Lock2>, MidValue2: Borrow<Mid2>, Value2: Borrow<V2>, MutValue: BorrowMut<V>, MutLock2: BorrowMut<Lock2>, MutMid2: BorrowMut<Mid2>, MutValue2: BorrowMut<V2>, G2_1: Fn(Value) -> Option<LockValue2> + 'static, S2_1: Fn(MutValue) -> Option<MutLock2> + 'static, L2: LockAccess<Lock2, MidValue2> + LockAccess<Lock2, MutMid2> + Clone + 'static, G2_2: Fn(MidValue2) -> Option<Value2> + 'static, S2_2: Fn(MutMid2) -> Option<MutValue2> + 'static,

Chain with another LockKp for multi-level lock access (then_lock convention)

This allows you to chain through multiple lock levels: Root -> Lock1 -> Mid1 -> Lock2 -> Mid2 -> Value

§Cloning Behavior - ALL CLONES ARE SHALLOW

This method requires two types of cloning, both SHALLOW:

  1. L2: Clone (line 261): Clones the lock accessor trait object

    • For ArcMutexAccess<T>: Only clones PhantomData (zero-cost)
    • No data is cloned, just the lock access behavior
  2. Lock2: Clone (line 287): Clones the lock container

    • For Arc<Mutex<T>>: Only increments Arc reference count
    • The actual data T inside the Mutex is NOT cloned
    • This is necessary to satisfy borrow checker in closure context

Performance: Both clones are O(1) operations with no deep data copying

§Example
// Root -> Arc<Mutex<Mid1>> -> Mid1 -> Arc<Mutex<Mid2>> -> Mid2 -> String
let lock_kp1 = LockKp::new(root_to_lock1, ArcMutexAccess::new(), lock1_to_mid1);
let lock_kp2 = LockKp::new(mid1_to_lock2, ArcMutexAccess::new(), mid2_to_value);

let chained = lock_kp1.then_lock(lock_kp2);
Source

pub fn then_async<AsyncKp>( self, async_kp: AsyncKp, ) -> KpThenAsyncKeyPath<R, V, <AsyncKp::Value as KeyPathValueTarget>::Target, Root, Value, AsyncKp::Value, MutRoot, MutValue, AsyncKp::MutValue, Self, AsyncKp>
where V: 'static + Clone, Value: Borrow<V>, MutValue: BorrowMut<V>, AsyncKp: AsyncKeyPathLike<Value, MutValue>, AsyncKp::Value: KeyPathValueTarget + Borrow<<AsyncKp::Value as KeyPathValueTarget>::Target>, AsyncKp::MutValue: BorrowMut<<AsyncKp::Value as KeyPathValueTarget>::Target>, <AsyncKp::Value as KeyPathValueTarget>::Target: 'static,

Chain with an async keypath. Use .get(&root).await on the returned keypath. When AsyncKp::Value is a reference type (&T / &mut T), V2 is inferred as T via crate::KeyPathValueTarget.

Trait Implementations§

Source§

impl<R: Clone, Lock: Clone, Mid: Clone, V: Clone, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2> Clone for LockKp<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2>
where Root: Borrow<R> + Clone, LockValue: Borrow<Lock> + Clone, MidValue: Borrow<Mid> + Clone, Value: Borrow<V> + Clone, MutRoot: BorrowMut<R> + Clone, MutLock: BorrowMut<Lock> + Clone, MutMid: BorrowMut<Mid> + Clone, MutValue: BorrowMut<V> + Clone, G1: Fn(Root) -> Option<LockValue> + Clone, S1: Fn(MutRoot) -> Option<MutLock> + Clone, L: LockAccess<Lock, MidValue> + LockAccess<Lock, MutMid> + Clone, G2: Fn(MidValue) -> Option<Value> + Clone, S2: Fn(MutMid) -> Option<MutValue> + Clone,

Source§

fn clone( &self, ) -> LockKp<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2> SyncKeyPathLike<Root, Value, MutRoot, MutValue> for LockKp<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2>
where Root: Borrow<R>, LockValue: Borrow<Lock>, MidValue: Borrow<Mid>, Value: Borrow<V>, MutRoot: BorrowMut<R>, MutLock: BorrowMut<Lock>, MutMid: BorrowMut<Mid>, MutValue: BorrowMut<V>, G1: Fn(Root) -> Option<LockValue>, S1: Fn(MutRoot) -> Option<MutLock>, L: LockAccess<Lock, MidValue> + LockAccess<Lock, MutMid>, G2: Fn(MidValue) -> Option<Value>, S2: Fn(MutMid) -> Option<MutValue>, V: Clone,

Source§

fn sync_get(&self, root: Root) -> Option<Value>

Source§

fn sync_get_mut(&self, root: MutRoot) -> Option<MutValue>

Auto Trait Implementations§

§

impl<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2> Freeze for LockKp<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2>
where L: Freeze, G1: Freeze, S1: Freeze, G2: Freeze, S2: Freeze,

§

impl<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2> RefUnwindSafe for LockKp<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2>

§

impl<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2> Send for LockKp<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2>
where L: Send, G1: Send, S1: Send, G2: Send, S2: Send, R: Send, Lock: Send, Root: Send, LockValue: Send, MutRoot: Send, MutLock: Send, Mid: Send, V: Send, MidValue: Send, Value: Send, MutMid: Send, MutValue: Send,

§

impl<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2> Sync for LockKp<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2>
where L: Sync, G1: Sync, S1: Sync, G2: Sync, S2: Sync, R: Sync, Lock: Sync, Root: Sync, LockValue: Sync, MutRoot: Sync, MutLock: Sync, Mid: Sync, V: Sync, MidValue: Sync, Value: Sync, MutMid: Sync, MutValue: Sync,

§

impl<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2> Unpin for LockKp<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2>
where L: Unpin, G1: Unpin, S1: Unpin, G2: Unpin, S2: Unpin, R: Unpin, Lock: Unpin, Root: Unpin, LockValue: Unpin, MutRoot: Unpin, MutLock: Unpin, Mid: Unpin, V: Unpin, MidValue: Unpin, Value: Unpin, MutMid: Unpin, MutValue: Unpin,

§

impl<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2> UnwindSafe for LockKp<R, Lock, Mid, V, Root, LockValue, MidValue, Value, MutRoot, MutLock, MutMid, MutValue, G1, S1, L, G2, S2>
where L: UnwindSafe, G1: UnwindSafe, S1: UnwindSafe, G2: UnwindSafe, S2: UnwindSafe, R: UnwindSafe, Lock: UnwindSafe, Root: UnwindSafe, LockValue: UnwindSafe, MutRoot: UnwindSafe, MutLock: UnwindSafe, Mid: UnwindSafe, V: UnwindSafe, MidValue: UnwindSafe, Value: UnwindSafe, MutMid: UnwindSafe, MutValue: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.