Trait recasting::Recast

source ·
pub trait Recast<Item> {
    // Required method
    fn recast<R: Recaster<Item = Item>>(
        &mut self,
        recaster: &R
    ) -> Result<(), <R as Recaster>::Item>;
}
Expand description

A trait implemented for structures that have Items that should be Recasted by a Recaster.

// using `Recaster` and `Recast` on the
// `Arena` from the `triple_arena` crate
use recasting::{Recaster, Recast};
use triple_arena::{Arena, Ptr, ptr_struct};

ptr_struct!(P0; Q1);

// `triple_arena` defines `Ptr`s with `Ptr: Recast<Self>` and implements
// this in the `ptr_struct` macro
/*
impl $crate::Recast<Self> for $struct_name {
    fn recast<R: $crate::Recaster<Item = Self>>(&mut self, recaster: &R)
        -> Result<(), <R as $crate::Recaster>::Item> {
        recaster.recast_item(self)
    }
}
*/

// An example some user structure. `Recast` was ultimately made for
// complicated structures that can have the `Item` in various fields.
// `Ptr`s are often used in structures that have references stored
// in arbitrary ways that aren't tree-like like in Rust's `&` and
// `&mut` references. This becomes a problem when we want to do
// something like serialize the structure, because the capacity
// of the `Arena`s would never decrease. Unless, we could
// ergonomically map all the `Ptr`s to new values from
// `Arena::compress_and_shrink`.
#[derive(Debug, PartialEq, Eq)]
struct Entry(u64, Vec<P0>, Q1);
struct Structure {
    p0_arena: Arena<P0, Entry>,
    // some `P0`s that are stored externally to the arena
    external: Vec<P0>,
    // an arena that is keyed by `Q1` instead of `P0`
    q1_arena: Arena<Q1, i32>,
}

impl Recast<P0> for Entry {
    fn recast<R: Recaster<Item = P0>>(&mut self, recaster: &R)
        -> Result<(), <R as Recaster>::Item> {
        // we can do this because of the `impl` of `Recast` for `Vec`, which
        // recasts all the entries
        self.1.recast(recaster)?;
        // the `.0` and `.1` fields are left untouched, since they
        // do not have `P0` values that would need to be recast
        Ok(())
    }
}

// Because we used an external associated type for the `Recast` trait,
// we can `impl` multiple times to be able to recast the same struct
// with recasters with different `Item`s.
impl Recast<Q1> for Entry {
    fn recast<R: Recaster<Item = Q1>>(&mut self, recaster: &R)
        -> Result<(), <R as Recaster>::Item> {
        // recast the `Q1`
        self.2.recast(recaster)?;
        Ok(())
    }
}

impl Recast<P0> for Structure {
    fn recast<R: Recaster<Item = P0>>(&mut self, recaster: &R)
        -> Result<(), <R as Recaster>::Item> {
        self.p0_arena.recast(recaster)?;
        // `external` has some `P0`s we need to recast so that they
        // agree with elsewhere in the structure.
        self.external.recast(recaster)?;
        // This line when uncommented results in an error because
        // there is not a `impl Recast<P0> for i32`, and we don't
        // need it because there are no `P0`s stored in `q1_arena`.
        //self.q1_arena.recast(recaster)?;

        // Note that if you have multiple collections with the same
        // type of key, you should change it with wrappers to a
        // different struct to prevent confusion (in `triple_arena`
        // we can use `ptr_struct` to create multiple structs to
        // represent different validity spaces of the different
        // arenas within the same structure, or otherwise use
        // generics to enforce a virtual difference).
        // If for some reason the same item absolutely needs to be
        // used in keys to more than one collection (e.x. we have
        // an `Arena<P0, _>` and an external `HashSet<P0>` that is
        // also keyed by `P0`), the recasting impl needs to empty
        // all collections except for the collection that the
        // `Recaster` is derived from. Then, the keys are recasted
        // externally and reinserted, or otherwise regenerated.
        Ok(())
    }
}

impl Recast<Q1> for Structure {
    fn recast<R: Recaster<Item = Q1>>(&mut self, recaster: &R)
        -> Result<(), <R as Recaster>::Item> {
        // the `Entry`s have `Q1` in them, this will delegate to the
        // `Recast<Q1> for Entry` impl
        self.p0_arena.recast(recaster)?;
        Ok(())
    }
}

impl Structure {
    fn recast_q1(&mut self) -> Result<Arena<Q1, Q1>, Q1> {
        // for this example we will use the recaster generated from
        // `compress_and_shrink_recaster`. This function rekeys
        // `q1_arena` and creates a mapping of the old keys to the
        // new.
        let recaster = self.q1_arena.compress_and_shrink_recaster();
        // Immediately afterwards, we need to recast all the values.
        // If we were to do anything else like call some function
        // that tries to index `q1_arena`, the operations would fail
        // because all other `Q1`s besides the keys (and just the
        // keys, if `q1_arena` had values with `Q1`s in them, they
        // would still reflect the old key mapping) are based on the
        // old keying. Calling `recast` will fix all that if we
        // implemented it correctly.
        self.recast(&recaster)?;
        // it is encouraged to have all the relevant `Q1`s self
        // contained within `Structure`, but if needed we could also
        // return the `recaster` for more external things.
        Ok(recaster)
    }

    fn recast_p0(&mut self) -> Result<Arena<P0, P0>, P0> {
        // Note an `Err` gets returned by `recast` if it encounters
        // a `P0` that was not contained as a key in the `p0_arena`
        // upon the call to acquire a recaster. If `Structure` is
        // using some kind of convention where invalid items could
        // be kept, they need to be purged by some routine here before
        // the `compress_and_shrink_recaster` call, or a custom
        // `Recaster` could be defined to be a no-op on unkown keys.
        let recaster = self.p0_arena.compress_and_shrink_recaster();
        self.recast(&recaster)?;
        Ok(recaster)
    }
}

let mut structure = Structure {
    p0_arena: Arena::new(),
    external: vec![],
    q1_arena: Arena::new()
};
// do some random inserts and removals
let q1_0 = structure.q1_arena.insert(-1);
let mut q1_1 = structure.q1_arena.insert(-2);
structure.q1_arena.remove(q1_0).unwrap();
let p0_0 = structure.p0_arena.insert(Entry(1, vec![], q1_1));
let mut p0_1 = structure.p0_arena.insert(Entry(2, vec![], q1_1));
let mut p0_2 = structure.p0_arena.insert(Entry(42, vec![p0_1], q1_1));
structure.p0_arena.remove(p0_0).unwrap();

let p0_recaster = structure.recast_p0().unwrap();
let q1_recaster = structure.recast_q1().unwrap();

// now everything within the `Structure` is recast, but note
// that the items we kept outside are invalid now and would
// need to be recast to be used for the new mapping

let old_q1_1 = q1_1;
assert!(structure.q1_arena.get(old_q1_1).is_none());
q1_1.recast(&q1_recaster).unwrap();
assert_eq!(structure.q1_arena.get(q1_1), Some(-2).as_ref());

let old_p0_1 = p0_1;
let old_p0_2 = p0_2;
p0_1.recast(&p0_recaster).unwrap();
p0_2.recast(&p0_recaster).unwrap();

assert_eq!(
    *structure.p0_arena.get(p0_2).unwrap(),
    Entry(42, vec![p0_1], q1_1)
);
// the structure relations are preserved despite the `Ptr`s
// changing
assert_ne!(old_p0_1, p0_1);
assert_ne!(old_p0_2, p0_2);
assert_ne!(old_q1_1, q1_1);

Required Methods§

source

fn recast<R: Recaster<Item = Item>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

Rewrites all the <R as Recaster>::Items of self according to the <recaster as Recaster>::map.

Errors

If the recaster encounters an item it does not recognize, it returns that item. Note that the state of self from before the recast may be unrecoverable (the structure can remain partially recast), and errors should only be encountered if these traits were used wrongly.

Implementations on Foreign Types§

source§

impl<Z, A: Recast<Z>, B: Recast<Z>, C: Recast<Z>, D: Recast<Z>, E: Recast<Z>, F: Recast<Z>, G: Recast<Z>> Recast<Z> for (A, B, C, D, E, F, G)

source§

fn recast<R: Recaster<Item = Z>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<I> Recast<I> for ()

source§

fn recast<R: Recaster<Item = I>>( &mut self, _recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<isize> for isize

source§

fn recast<R: Recaster<Item = isize>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<Z, A: Recast<Z>, B: Recast<Z>, C: Recast<Z>, D: Recast<Z>, E: Recast<Z>, F: Recast<Z>, G: Recast<Z>, H: Recast<Z>, I: Recast<Z>, J: Recast<Z>> Recast<Z> for (A, B, C, D, E, F, G, H, I, J)

source§

fn recast<R: Recaster<Item = Z>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<i16> for i16

source§

fn recast<R: Recaster<Item = i16>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<Z, A: Recast<Z>> Recast<Z> for (A,)

source§

fn recast<R: Recaster<Item = Z>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<NonZeroI16> for NonZeroI16

source§

fn recast<R: Recaster<Item = NonZeroI16>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<i8> for i8

source§

fn recast<R: Recaster<Item = i8>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<NonZeroU16> for NonZeroU16

source§

fn recast<R: Recaster<Item = NonZeroU16>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<usize> for usize

source§

fn recast<R: Recaster<Item = usize>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<u16> for u16

source§

fn recast<R: Recaster<Item = u16>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<I, T: Recast<I>> Recast<I> for LinkedList<T>

source§

fn recast<R: Recaster<Item = I>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<u64> for u64

source§

fn recast<R: Recaster<Item = u64>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<Z, A: Recast<Z>, B: Recast<Z>, C: Recast<Z>, D: Recast<Z>, E: Recast<Z>, F: Recast<Z>> Recast<Z> for (A, B, C, D, E, F)

source§

fn recast<R: Recaster<Item = Z>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<I, T: Recast<I>, const N: usize> Recast<I> for [T; N]

source§

fn recast<R: Recaster<Item = I>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<NonZeroI128> for NonZeroI128

source§

fn recast<R: Recaster<Item = NonZeroI128>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<u128> for u128

source§

fn recast<R: Recaster<Item = u128>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<I, T: Recast<I>> Recast<I> for Option<T>

source§

fn recast<R: Recaster<Item = I>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<NonZeroUsize> for NonZeroUsize

source§

fn recast<R: Recaster<Item = NonZeroUsize>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<Z, A: Recast<Z>, B: Recast<Z>, C: Recast<Z>, D: Recast<Z>, E: Recast<Z>, F: Recast<Z>, G: Recast<Z>, H: Recast<Z>, I: Recast<Z>> Recast<Z> for (A, B, C, D, E, F, G, H, I)

source§

fn recast<R: Recaster<Item = Z>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<Z, A: Recast<Z>, B: Recast<Z>, C: Recast<Z>, D: Recast<Z>, E: Recast<Z>, F: Recast<Z>, G: Recast<Z>, H: Recast<Z>> Recast<Z> for (A, B, C, D, E, F, G, H)

source§

fn recast<R: Recaster<Item = Z>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<i128> for i128

source§

fn recast<R: Recaster<Item = i128>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<NonZeroU8> for NonZeroU8

source§

fn recast<R: Recaster<Item = NonZeroU8>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<i32> for i32

source§

fn recast<R: Recaster<Item = i32>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<NonZeroI8> for NonZeroI8

source§

fn recast<R: Recaster<Item = NonZeroI8>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<Z, A: Recast<Z>, B: Recast<Z>, C: Recast<Z>> Recast<Z> for (A, B, C)

source§

fn recast<R: Recaster<Item = Z>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<NonZeroU128> for NonZeroU128

source§

fn recast<R: Recaster<Item = NonZeroU128>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<NonZeroU32> for NonZeroU32

source§

fn recast<R: Recaster<Item = NonZeroU32>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<I, T: Recast<I>> Recast<I> for Vec<T>

source§

fn recast<R: Recaster<Item = I>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<Z, A: Recast<Z>, B: Recast<Z>, C: Recast<Z>, D: Recast<Z>, E: Recast<Z>, F: Recast<Z>, G: Recast<Z>, H: Recast<Z>, I: Recast<Z>, J: Recast<Z>, K: Recast<Z>> Recast<Z> for (A, B, C, D, E, F, G, H, I, J, K)

source§

fn recast<R: Recaster<Item = Z>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<bool> for bool

source§

fn recast<R: Recaster<Item = bool>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<Z, A: Recast<Z>, B: Recast<Z>> Recast<Z> for (A, B)

source§

fn recast<R: Recaster<Item = Z>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<char> for char

source§

fn recast<R: Recaster<Item = char>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<NonZeroU64> for NonZeroU64

source§

fn recast<R: Recaster<Item = NonZeroU64>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<I, T: Recast<I>, E: Recast<I>> Recast<I> for Result<T, E>

source§

fn recast<R: Recaster<Item = I>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<i64> for i64

source§

fn recast<R: Recaster<Item = i64>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<u32> for u32

source§

fn recast<R: Recaster<Item = u32>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<Z, A: Recast<Z>, B: Recast<Z>, C: Recast<Z>, D: Recast<Z>, E: Recast<Z>> Recast<Z> for (A, B, C, D, E)

source§

fn recast<R: Recaster<Item = Z>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<f64> for f64

source§

fn recast<R: Recaster<Item = f64>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<Z, A: Recast<Z>, B: Recast<Z>, C: Recast<Z>, D: Recast<Z>> Recast<Z> for (A, B, C, D)

source§

fn recast<R: Recaster<Item = Z>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<I, T: Recast<I>> Recast<I> for VecDeque<T>

source§

fn recast<R: Recaster<Item = I>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<I, T: Recast<I>> Recast<I> for [T]

source§

fn recast<R: Recaster<Item = I>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<u8> for u8

source§

fn recast<R: Recaster<Item = u8>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<NonZeroI64> for NonZeroI64

source§

fn recast<R: Recaster<Item = NonZeroI64>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<I, T: Recast<I>> Recast<I> for Box<T>

source§

fn recast<R: Recaster<Item = I>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<f32> for f32

source§

fn recast<R: Recaster<Item = f32>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<NonZeroIsize> for NonZeroIsize

source§

fn recast<R: Recaster<Item = NonZeroIsize>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl<Z, A: Recast<Z>, B: Recast<Z>, C: Recast<Z>, D: Recast<Z>, E: Recast<Z>, F: Recast<Z>, G: Recast<Z>, H: Recast<Z>, I: Recast<Z>, J: Recast<Z>, K: Recast<Z>, L: Recast<Z>> Recast<Z> for (A, B, C, D, E, F, G, H, I, J, K, L)

source§

fn recast<R: Recaster<Item = Z>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

source§

impl Recast<NonZeroI32> for NonZeroI32

source§

fn recast<R: Recaster<Item = NonZeroI32>>( &mut self, recaster: &R ) -> Result<(), <R as Recaster>::Item>

Implementors§