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

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

Structs

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

Traits

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.

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

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