[][src]Struct smart_access::AT

#[must_use]pub struct AT<CPS, List> { /* fields omitted */ }

A “reference” to some “location”.

With default Cps implementations (and with the detach feature disabled) every AT is usually a “path component” list of type

AT<&mut root, (..((((), I1), I2), I3) .. In)>

But beware! Starting with the version 0.5 there is a possibility of accidentally creating multilevel hierarchies like

AT<AT<&mut root, ((), I1)>, ((), I2)>

by using the at of Cps instead of its AT-override.

Moreover, the detach feature is now based on such nonflat structures.

Usage in function types

Though AT is exposed, it's strongly recommended to use impl Cps<View=T> as a return type of functions and Cps<View=T> bounds on their parameters.

But when needed (for example, due to some complex lifetimes), usage of AT can be facilitated by the path macro allowing one to write

AT<CPS, path!(I, J, K)>

instead of

AT<CPS, ((((), I), J), K)>

Detaching paths

Enabling detach feature allows one to detach ATs from their roots.

Without this feature only a single component can be detached:

use smart_access::Cps;

let mut foo = vec![vec![1,2], vec![3,4]];

let (foo_i, j) = foo.at(0).at(0).into();
assert!(foo_i.at(1).replace(5) == Some(2));

Note

Relevant only with the detach feature enabled.

If you pass a detached path to a function then you should use a Path: Attach<CPS::View, View=V> bound instead of a Cps<View=V> bound.

I.e.

fn replace_at<CPS: Cps, Path, V>(cps: CPS, path: Path, x: V) -> Option<V> where
    Path: Attach<CPS::View, View=V>,
{
    cps.attach(path).replace(x)
}

let mut vec = vec![1,2,3];

assert!(replace_at(&mut vec, detached_at(0), 4) == Some(1));
assert!(vec == vec![4,2,3]);

But sometimes an explicit AT can be useful (the example below is artificial and thus not very illuminating...):

use smart_access::*;

fn get_ij<CPS, U, V, W>(a_i: AT<CPS, path!(usize)>, j: usize) 
    -> impl Attach<W, View=V> where 
    CPS: Cps<View=W>,
    W: At<usize, View=U> + ?Sized,
    U: At<usize, View=V> + ?Sized,
    V: ?Sized,
{
    let (a,i) = a_i.into();
    let (_, path) = a.at(i).at(j).detach();

    path
}

let mut foo = vec![vec![1,2], vec![3,4]];
let path = get_ij(detached_at(1), 0);
 
assert!(foo.attach(path).replace(5) == Some(3));

Implementations

impl<CPS, List> AT<CPS, List>[src]

pub fn at<Index, View: ?Sized>(self, i: Index) -> AT<CPS, (List, Index)> where
    AT<CPS, List>: Cps<View = View>,
    View: At<Index>, 
[src]

Override for at of Cps.

Preserves flat structure.

impl<CPS: Cps, List> AT<CPS, List>[src]

pub fn detach(self) -> (CPS, DetachedPath<CPS::View, List>)[src]

Detaches the path starting from the nearest detach point.

Present only on detach.

Usage example

use smart_access::Cps;

let mut foo = vec![vec![vec![0]]];
let mut bar = vec![vec![vec![0]]];

let (_, detached) = foo.at(0).at(0).at(0).detach();

// Detached paths are cloneable (if indices are cloneable)
let the_same_path = detached.clone();

bar.attach(the_same_path).replace(1);
assert!(foo == vec![vec![vec![0]]]);
assert!(bar == vec![vec![vec![1]]]);

foo.attach(detached).replace(2);
assert!(foo == vec![vec![vec![2]]]);
assert!(bar == vec![vec![vec![1]]]);
 
let (_, path) = bar.at(0).at(0).detach();
bar.attach(path.at(0)).replace(3);
assert!(bar == vec![vec![vec![3]]]);

Trait Implementations

impl<CPS: Clone, List: Clone> Clone for AT<CPS, List>[src]

impl<CPS: Cps, Path> Cps for AT<CPS, Path> where
    Path: AtView<CPS::View>, 
[src]

access returns Some / None according to the rules described here

type View = Path::View

impl<CPS: Debug, List: Debug> Debug for AT<CPS, List>[src]

impl<CPS, Prev, I> From<AT<CPS, (Prev, I)>> for (AT<CPS, Prev>, I)[src]

AT can be broken apart to detach a single path component.

A more general attach/detach framework is accessible through the detach feature.

Auto Trait Implementations

impl<CPS, List> RefUnwindSafe for AT<CPS, List> where
    CPS: RefUnwindSafe,
    List: RefUnwindSafe

impl<CPS, List> Send for AT<CPS, List> where
    CPS: Send,
    List: Send

impl<CPS, List> Sync for AT<CPS, List> where
    CPS: Sync,
    List: Sync

impl<CPS, List> Unpin for AT<CPS, List> where
    CPS: Unpin,
    List: Unpin

impl<CPS, List> UnwindSafe for AT<CPS, List> where
    CPS: UnwindSafe,
    List: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.