Crate any_ref

Source
Expand description

any_ref is here to solve the problem that you are worry about have no idea carrying a struct with lifetime annotation anywhere. It’s alternative to take a look at owning_ref. One of the vital advantages of any_ref is that it allows you capture values with any type, not limited to references. Have a wonderful time with any_ref!

Pre-made types:

make_any_ref!(
   pub type Reference<T:'static + ?Sized> = for<'a> &'a T;
   pub type ReferenceMut<T:'static + ?Sized> = for<'a> &'a mut T;
);

§Example

use any_ref::{make_any_ref, AnyRef, Reference};

make_any_ref! {
    pub type _ReturnStr=for<'a> &'a str;
    pub(crate) type ReturnVec<T:'static> = for<'a> Vec<&'a T>;
    type _ReturnPhantomData<T:'static,const U:usize> = for<'lifetime> std::marker::PhantomData<&'lifetime (T,)>;
}

let moved_ar;
{
    let num = Box::new((1, 2, 3, 4));
    let ar = AnyRef::<ReturnVec<u16>, _>::new(num, |x| vec![&x.0, &x.1, &x.2, &x.3]);
    moved_ar = ar; // Move out of this scope
}
assert_eq!(moved_ar.get(), &vec![&1, &2, &3, &4]);

let moved_ar;
{
    let s = "hello world".to_string();
    let ar = AnyRef::<Reference<str>, _>::new(s, |x| &x[..5]);
    moved_ar = ar;
}
assert_eq!(*moved_ar.get(), "hello");

§To build multiple AnyRefs

use any_ref::{make_any_ref, AnyRef, Reference};
use std::rc::Rc;

let bytes: Rc<[u8]> = Rc::from((vec![1, 2, 3, 4, 5, 6]).into_boxed_slice());

let (first_half, second_half) = any_ref::build(bytes.clone(), |array, mut builder| {
    let split_at = array.len() / 2;
    (
        builder.build::<Reference<[u8]>>(&array[..split_at]),
        builder.build::<Reference<[u8]>>(&array[split_at..])
    )
});

assert_eq!(first_half.get(), &[1, 2, 3]);
assert_eq!(second_half.get(), &[4, 5, 6]);

§Stable Deref

It is worth noting that O must implement std::ops::Deref and the memory address of its target must be stable even if moved. In other words, the target O de-reference to must be allocated on the heap.

We use stable_deref_trait crate to realize this limitation. Please read its StableDeref passage for details.

Clone trait is also implemented for AnyRef, but it requires O to implements CloneStableDeref. That is, besides all the limitations of StableDeref, O requires deref to the same address when cloned. At present, only Rc and Arc implemented CloneStableDeref.

Re-exports§

pub use builder::build;
pub use type_substitute::*;

Modules§

builder
type_substitute
Internal traits and their implementation for &T and &mut T. It is not recommended to manually implement traits here and there is no need to know this traits for practical use. Please use make_any_ref macro if possible.

Macros§

make_any_ref

Structs§

AnyRef
The wrapper that holding O and the return type of T.

Traits§

CloneStableDeref
An unsafe marker trait for types where clones deref to the same address. This has all the requirements of StableDeref, and additionally requires that after calling clone(), both the old and new value deref to the same address. For example, Rc and Arc implement CloneStableDeref, but Box and Vec do not.
StableDeref
An unsafe marker trait for types that deref to a stable address, even when moved. For example, this is implemented by Box, Vec, Rc, Arc and String, among others. Even when a Box is moved, the underlying storage remains at a fixed location.

Functions§

new_any_ref
Create AnyRef. This function will be continue to use before we could use AnyRef::new.