Skip to main content

Kp

Struct Kp 

Source
pub struct Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
where Root: Borrow<R>, MutRoot: BorrowMut<R>, MutValue: BorrowMut<V>, G: Fn(Root) -> Option<Value>, S: Fn(MutRoot) -> Option<MutValue>,
{ /* private fields */ }
Expand description

AKp (AnyKeyPath) - Hides both Root and Value types Most flexible keypath type for heterogeneous collections Uses dynamic dispatch and type checking at runtime

§Mutation: get vs get_mut (setter path)

  • get uses the get closure (getter): Fn(Root) -> Option<Value>
  • get_mut uses the set closure (setter): Fn(MutRoot) -> Option<MutValue>

When mutating through a Kp, the setter path is used—get_mut invokes the set closure, not the get closure. The getter is for read-only access only.

Implementations§

Source§

impl<R, V> Kp<R, V, &'static R, &'static V, &'static mut R, &'static mut V, Box<dyn for<'b> Fn(&'b R) -> Option<&'b V>>, Box<dyn for<'b> Fn(&'b mut R) -> Option<&'b mut V>>>

Source

pub fn from_closures<G, S>(get: G, set: S) -> Self
where G: for<'b> Fn(&'b R) -> Option<&'b V> + 'static, S: for<'b> Fn(&'b mut R) -> Option<&'b mut V> + 'static,

Build a keypath from two closures (e.g. when they capture a variable like an index). Same pattern as Kp::new in lock.rs; use this when the keypath captures variables.

Source§

impl<R, V, Root, Value, MutRoot, MutValue, G, S> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
where Root: Borrow<R>, Value: Borrow<V>, MutRoot: BorrowMut<R>, MutValue: BorrowMut<V>, G: Fn(Root) -> Option<Value>, S: Fn(MutRoot) -> Option<MutValue>,

Source

pub fn new(get: G, set: S) -> Self

Source

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

Source

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

Source

pub fn then<SV, SubValue, MutSubValue, G2, S2>( self, next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>, ) -> Kp<R, SV, Root, SubValue, MutRoot, MutSubValue, impl Fn(Root) -> Option<SubValue> + use<SV, SubValue, MutSubValue, G2, S2, R, V, Root, Value, MutRoot, MutValue, G, S>, impl Fn(MutRoot) -> Option<MutSubValue> + use<SV, SubValue, MutSubValue, G2, S2, R, V, Root, Value, MutRoot, MutValue, G, S>>
where SubValue: Borrow<SV>, MutSubValue: BorrowMut<SV>, G2: Fn(Value) -> Option<SubValue>, S2: Fn(MutValue) -> Option<MutSubValue>, V: 'static,

Source

pub fn then_lock<Lock, Mid, V2, LockValue, MidValue, Value2, MutLock, MutMid, MutValue2, G1, S1, L, G2, S2>( self, lock_kp: LockKp<V, Lock, Mid, V2, Value, LockValue, MidValue, Value2, MutValue, MutLock, MutMid, MutValue2, G1, S1, L, G2, S2>, ) -> KpThenLockKp<R, V, V2, Root, Value, Value2, MutRoot, MutValue, MutValue2, Self, LockKp<V, Lock, Mid, V2, Value, LockValue, MidValue, Value2, MutValue, MutLock, MutMid, MutValue2, G1, S1, L, G2, S2>>
where V: 'static + Clone, V2: 'static, Value: Borrow<V>, Value2: Borrow<V2>, MutValue: BorrowMut<V>, MutValue2: BorrowMut<V2>, LockValue: Borrow<Lock>, MidValue: Borrow<Mid>, MutLock: BorrowMut<Lock>, MutMid: BorrowMut<Mid>, G1: Fn(Value) -> Option<LockValue>, S1: Fn(MutValue) -> Option<MutLock>, L: LockAccess<Lock, MidValue> + LockAccess<Lock, MutMid>, G2: Fn(MidValue) -> Option<Value2>, S2: Fn(MutMid) -> Option<MutValue2>,

Chain with a sync crate::lock::LockKp. Use .get(root) / .get_mut(root) on the returned keypath.

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, 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 (e.g. crate::async_lock::AsyncLockKp). Use .get(&root).await on the returned keypath. When AsyncKp::Value is a reference type (&T / &mut T), V2 is inferred as T via KeyPathValueTarget.

Source

pub fn map<MappedValue, F>( &self, mapper: F, ) -> Kp<R, MappedValue, Root, MappedValue, MutRoot, MappedValue, impl Fn(Root) -> Option<MappedValue>, impl Fn(MutRoot) -> Option<MappedValue>>
where F: Fn(&V) -> MappedValue + Copy + 'static, V: 'static, MappedValue: 'static,

Map the value through a transformation function Returns a new keypath that transforms the value when accessed

§Example
use rust_key_paths::{Kp, KpType};
struct User { name: String }
let user = User { name: "Alice".to_string() };
let name_kp = KpType::new(|u: &User| Some(&u.name), |u: &mut User| Some(&mut u.name));
let len_kp = name_kp.map(|name: &String| name.len());
assert_eq!(len_kp.get(&user), Some(5));
Source

pub fn filter<F>( &self, predicate: F, ) -> Kp<R, V, Root, Value, MutRoot, MutValue, impl Fn(Root) -> Option<Value>, impl Fn(MutRoot) -> Option<MutValue>>
where F: Fn(&V) -> bool + Copy + 'static, V: 'static,

Filter the value based on a predicate Returns None if the predicate returns false, otherwise returns the value

§Example
use rust_key_paths::{Kp, KpType};
struct User { age: i32 }
let user = User { age: 30 };
let age_kp = KpType::new(|u: &User| Some(&u.age), |u: &mut User| Some(&mut u.age));
let adult_kp = age_kp.filter(|age: &i32| *age >= 18);
assert_eq!(adult_kp.get(&user), Some(&30));
Source

pub fn filter_map<MappedValue, F>( &self, mapper: F, ) -> Kp<R, MappedValue, Root, MappedValue, MutRoot, MappedValue, impl Fn(Root) -> Option<MappedValue>, impl Fn(MutRoot) -> Option<MappedValue>>
where F: Fn(&V) -> Option<MappedValue> + Copy + 'static, V: 'static, MappedValue: 'static,

Map and flatten - useful when mapper returns an Option

§Example
use rust_key_paths::{Kp, KpType};
struct User { middle_name: Option<String> }
let user = User { middle_name: Some("M.".to_string()) };
let middle_kp = KpType::new(|u: &User| Some(&u.middle_name), |_| None);
let first_char_kp = middle_kp.filter_map(|opt: &Option<String>| {
    opt.as_ref().and_then(|s| s.chars().next())
});
Source

pub fn flat_map<I, Item, F>(&self, mapper: F) -> impl Fn(Root) -> Vec<Item>
where F: Fn(&V) -> I + 'static, V: 'static, I: IntoIterator<Item = Item>, Item: 'static,

Flat map - maps to an iterator and flattens Useful when the value is a collection and you want to iterate over it

§Example
use rust_key_paths::{Kp, KpType};
struct User { tags: Vec<&'static str> }
let user = User { tags: vec!["rust", "web"] };
let tags_kp = KpType::new(|u: &User| Some(&u.tags), |_| None);
// Use with a closure that returns an iterator
Source

pub fn inspect<F>( &self, inspector: F, ) -> Kp<R, V, Root, Value, MutRoot, MutValue, impl Fn(Root) -> Option<Value>, impl Fn(MutRoot) -> Option<MutValue>>
where F: Fn(&V) + Copy + 'static, V: 'static,

Apply a function for its side effects and return the value

§Example
use rust_key_paths::{Kp, KpType};
struct User { name: String }
let user = User { name: "Alice".to_string() };
let name_kp = KpType::new(|u: &User| Some(&u.name), |_| None);
name_kp.inspect(|name| println!("Name: {}", name)).get(&user);
Source

pub fn fold_value<Acc, F>(&self, init: Acc, folder: F) -> impl Fn(Root) -> Acc
where F: Fn(Acc, &V) -> Acc + 'static, V: 'static, Acc: Copy + 'static,

Fold/reduce the value using an accumulator function Useful when the value is a collection

§Example
use rust_key_paths::{Kp, KpType};
struct User { scores: Vec<i32> }
let user = User { scores: vec![85, 92, 78] };
let scores_kp = KpType::new(|u: &User| Some(&u.scores), |_| None);
let sum = scores_kp.fold_value(0, |acc, scores| {
    scores.iter().sum::<i32>() + acc
})(&user);
Source

pub fn any<F>(&self, predicate: F) -> impl Fn(Root) -> bool
where F: Fn(&V) -> bool + 'static, V: 'static,

Check if any element satisfies a predicate (for collection values)

§Example
use rust_key_paths::{Kp, KpType};
struct User { scores: Vec<i32> }
let user = User { scores: vec![85, 92, 78] };
let scores_kp = KpType::new(|u: &User| Some(&u.scores), |_| None);
let has_high = scores_kp.any(|scores| scores.iter().any(|&s| s > 90));
assert!(has_high(&user));
Source

pub fn all<F>(&self, predicate: F) -> impl Fn(Root) -> bool
where F: Fn(&V) -> bool + 'static, V: 'static,

Check if all elements satisfy a predicate (for collection values)

§Example
use rust_key_paths::{Kp, KpType};
struct User { scores: Vec<i32> }
let user = User { scores: vec![85, 92, 78] };
let scores_kp = KpType::new(|u: &User| Some(&u.scores), |_| None);
let all_passing = scores_kp.all(|scores| scores.iter().all(|&s| s >= 70));
assert!(all_passing(&user));
Source

pub fn count_items<F>(&self, counter: F) -> impl Fn(Root) -> Option<usize>
where F: Fn(&V) -> usize + 'static, V: 'static,

Count elements in a collection value

§Example
use rust_key_paths::{Kp, KpType};
struct User { tags: Vec<&'static str> }
let user = User { tags: vec!["rust", "web", "backend"] };
let tags_kp = KpType::new(|u: &User| Some(&u.tags), |_| None);
let count = tags_kp.count_items(|tags| tags.len());
assert_eq!(count(&user), Some(3));
Source

pub fn find_in<Item, F>(&self, finder: F) -> impl Fn(Root) -> Option<Item>
where F: Fn(&V) -> Option<Item> + 'static, V: 'static, Item: 'static,

Find first element matching predicate in a collection value

§Example
use rust_key_paths::{Kp, KpType};
struct User { scores: Vec<i32> }
let user = User { scores: vec![85, 92, 78, 95] };
let scores_kp = KpType::new(|u: &User| Some(&u.scores), |_| None);
let first_high = scores_kp.find_in(|scores| {
    scores.iter().find(|&&s| s > 90).copied()
});
assert_eq!(first_high(&user), Some(92));
Source

pub fn take<Output, F>( &self, n: usize, taker: F, ) -> impl Fn(Root) -> Option<Output>
where F: Fn(&V, usize) -> Output + 'static, V: 'static, Output: 'static,

Take first N elements from a collection value

§Example
use rust_key_paths::{Kp, KpType};
struct User { tags: Vec<&'static str> }
let user = User { tags: vec!["a", "b", "c", "d"] };
let tags_kp = KpType::new(|u: &User| Some(&u.tags), |_| None);
let first_two = tags_kp.take(2, |tags, n| tags.iter().take(n).cloned().collect::<Vec<_>>());
Source

pub fn skip<Output, F>( &self, n: usize, skipper: F, ) -> impl Fn(Root) -> Option<Output>
where F: Fn(&V, usize) -> Output + 'static, V: 'static, Output: 'static,

Skip first N elements from a collection value

§Example
use rust_key_paths::{Kp, KpType};
struct User { tags: Vec<&'static str> }
let user = User { tags: vec!["a", "b", "c", "d"] };
let tags_kp = KpType::new(|u: &User| Some(&u.tags), |_| None);
let after_two = tags_kp.skip(2, |tags, n| tags.iter().skip(n).cloned().collect::<Vec<_>>());
Source

pub fn partition_value<Output, F>( &self, partitioner: F, ) -> impl Fn(Root) -> Option<Output>
where F: Fn(&V) -> Output + 'static, V: 'static, Output: 'static,

Partition a collection value into two groups based on predicate

§Example
use rust_key_paths::{Kp, KpType};
struct User { scores: Vec<i32> }
let user = User { scores: vec![85, 92, 65, 95, 72] };
let scores_kp = KpType::new(|u: &User| Some(&u.scores), |_| None);
let (passing, failing): (Vec<i32>, Vec<i32>) = scores_kp.partition_value(|scores| {
    scores.iter().copied().partition(|&s| s >= 70)
})(&user).unwrap();
Source

pub fn min_value<Item, F>(&self, min_fn: F) -> impl Fn(Root) -> Option<Item>
where F: Fn(&V) -> Option<Item> + 'static, V: 'static, Item: 'static,

Get min value from a collection

§Example
use rust_key_paths::{Kp, KpType};
struct User { scores: Vec<i32> }
let user = User { scores: vec![85, 92, 78] };
let scores_kp = KpType::new(|u: &User| Some(&u.scores), |_| None);
let min = scores_kp.min_value(|scores| scores.iter().min().copied());
assert_eq!(min(&user), Some(78));
Source

pub fn max_value<Item, F>(&self, max_fn: F) -> impl Fn(Root) -> Option<Item>
where F: Fn(&V) -> Option<Item> + 'static, V: 'static, Item: 'static,

Get max value from a collection

§Example
use rust_key_paths::{Kp, KpType};
struct User { scores: Vec<i32> }
let user = User { scores: vec![85, 92, 78] };
let scores_kp = KpType::new(|u: &User| Some(&u.scores), |_| None);
let max = scores_kp.max_value(|scores| scores.iter().max().copied());
assert_eq!(max(&user), Some(92));
Source

pub fn sum_value<Sum, F>(&self, sum_fn: F) -> impl Fn(Root) -> Option<Sum>
where F: Fn(&V) -> Sum + 'static, V: 'static, Sum: 'static,

Sum numeric values in a collection

§Example
use rust_key_paths::{Kp, KpType};
struct User { scores: Vec<i32> }
let user = User { scores: vec![85, 92, 78] };
let scores_kp = KpType::new(|u: &User| Some(&u.scores), |_| None);
let sum = scores_kp.sum_value(|scores: &Vec<i32>| scores.iter().sum());
assert_eq!(sum(&user), Some(255));
Source

pub fn chain<SV, SubValue, MutSubValue, G2, S2>( self, next: Kp<V, SV, Value, SubValue, MutValue, MutSubValue, G2, S2>, ) -> Kp<R, SV, Root, SubValue, MutRoot, MutSubValue, impl Fn(Root) -> Option<SubValue>, impl Fn(MutRoot) -> Option<MutSubValue>>
where SubValue: Borrow<SV>, MutSubValue: BorrowMut<SV>, G2: Fn(Value) -> Option<SubValue>, S2: Fn(MutValue) -> Option<MutSubValue>, V: 'static,

Chain this keypath with another to create a composition Alias for then with a more descriptive name

Source

pub fn for_arc<'b>( &self, ) -> Kp<Arc<R>, V, Arc<R>, Value, Arc<R>, MutValue, impl Fn(Arc<R>) -> Option<Value>, impl Fn(Arc<R>) -> Option<MutValue>>
where R: 'b, V: 'b, Root: for<'a> From<&'a R>, MutRoot: for<'a> From<&'a mut R>,

Source

pub fn for_box<'a>( &self, ) -> Kp<Box<R>, V, Box<R>, Value, Box<R>, MutValue, impl Fn(Box<R>) -> Option<Value>, impl Fn(Box<R>) -> Option<MutValue>>
where R: 'a, V: 'a, Root: for<'b> From<&'b R>, MutRoot: for<'b> From<&'b mut R>,

Source§

impl<R, Root, MutRoot, G, S> Kp<R, R, Root, Root, MutRoot, MutRoot, G, S>
where Root: Borrow<R>, MutRoot: BorrowMut<R>, G: Fn(Root) -> Option<Root>, S: Fn(MutRoot) -> Option<MutRoot>,

Source

pub fn identity_typed() -> Kp<R, R, Root, Root, MutRoot, MutRoot, fn(Root) -> Option<Root>, fn(MutRoot) -> Option<MutRoot>>

Source

pub fn identity<'a>() -> KpType<'a, R, R>

Trait Implementations§

Source§

impl<R: Clone, V: Clone, Root, Value: Clone, MutRoot, MutValue, G, S> Clone for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
where Root: Borrow<R> + Clone, MutRoot: BorrowMut<R> + Clone, MutValue: BorrowMut<V> + Clone, G: Fn(Root) -> Option<Value> + Clone, S: Fn(MutRoot) -> Option<MutValue> + Clone,

Source§

fn clone(&self) -> Kp<R, V, Root, Value, MutRoot, MutValue, G, S>

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, V, Root, Value, MutRoot, MutValue, G, S> SyncKeyPathLike<Root, Value, MutRoot, MutValue> for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
where Root: Borrow<R>, Value: Borrow<V>, MutRoot: BorrowMut<R>, MutValue: BorrowMut<V>, G: Fn(Root) -> Option<Value>, S: Fn(MutRoot) -> Option<MutValue>,

Source§

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

Get an immutable reference through the keypath (sync, non-blocking). Read more
Source§

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

Get a mutable reference through the keypath (sync, non-blocking). Read more

Auto Trait Implementations§

§

impl<R, V, Root, Value, MutRoot, MutValue, G, S> Freeze for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
where G: Freeze, S: Freeze,

§

impl<R, V, Root, Value, MutRoot, MutValue, G, S> RefUnwindSafe for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>

§

impl<R, V, Root, Value, MutRoot, MutValue, G, S> Send for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
where G: Send, S: Send, R: Send, V: Send, Root: Send, Value: Send, MutRoot: Send, MutValue: Send,

§

impl<R, V, Root, Value, MutRoot, MutValue, G, S> Sync for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
where G: Sync, S: Sync, R: Sync, V: Sync, Root: Sync, Value: Sync, MutRoot: Sync, MutValue: Sync,

§

impl<R, V, Root, Value, MutRoot, MutValue, G, S> Unpin for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
where G: Unpin, S: Unpin, R: Unpin, V: Unpin, Root: Unpin, Value: Unpin, MutRoot: Unpin, MutValue: Unpin,

§

impl<R, V, Root, Value, MutRoot, MutValue, G, S> UnwindSafe for Kp<R, V, Root, Value, MutRoot, MutValue, G, S>
where G: UnwindSafe, S: UnwindSafe, R: UnwindSafe, V: UnwindSafe, Root: UnwindSafe, Value: UnwindSafe, MutRoot: 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.