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 AnyRef
s
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
.