Trait starlark::coerce::Coerce

source ·
pub unsafe trait Coerce<To: ?Sized> { }
Expand description

A marker trait such that the existence of From: Coerce<To> implies that From can be treat as To without any data manipulation. Particularly useful for containers, e.g. Vec<From> can be treated as Vec<To> in O(1). If such an instance is available, you can use coerce to perform the conversion.

Importantly, you must make sure Rust does not change the type representation between the different types (typically using a repr directive), and it must be safe for the From to be treated as To, namely same (or less restrictive) alignment, no additional invariants, value can be dropped as To.

One use of Coerce is around newtype wrappers:

use starlark::coerce::coerce;
use starlark::coerce::Coerce;
#[repr(transparent)]
#[derive(Debug, Coerce)]
struct Wrapper(String);

let value = vec![Wrapper("hello".to_owned()), Wrapper("world".to_owned())];
assert_eq!(coerce::<_, &Vec<String>>(&value).join(" "), "hello world");
let mut value = coerce::<_, Vec<String>>(value);
assert_eq!(value.pop(), Some("world".to_owned()));

Another involves containers:

use starlark::coerce::coerce;
use starlark::coerce::Coerce;
#[derive(Coerce)]
#[repr(C)]
struct Container<T>(i32, T);

let value = Container(20, Wrapper("twenty".to_owned()));
assert_eq!(coerce::<_, &Container<String>>(&value).1, "twenty");

If you only need coerce on newtype references, then the ref-cast crate provides that, along with automatic derivations (no unsafe required).

Implementations on Foreign Types§

source§

impl Coerce<str> for str

source§

impl Coerce<()> for ()

source§

impl Coerce<FrozenTupleRef> for [FrozenValue]

source§

impl Coerce<String> for String

source§

impl<'a, From, To: ?Sized> Coerce<&'a To> for &'a From
where From: Coerce<To> + ?Sized,

source§

impl<'v> Coerce<ListRef<'v>> for [Value<'v>]

source§

impl<'v> Coerce<TupleRef<'v>> for [Value<'v>]

source§

impl<From1: Coerce<To1>, From2: Coerce<To2>, To1, To2> Coerce<(To1, To2)> for (From1, From2)

source§

impl<From1: Coerce<To1>, To1> Coerce<(To1,)> for (From1,)

source§

impl<From, To> Coerce<[To]> for [From]
where From: Coerce<To>,

source§

impl<From, To> Coerce<Vec<To>> for Vec<From>
where From: Coerce<To>,

source§

impl<From, To> Coerce<PhantomData<To>> for PhantomData<From>

source§

impl<From, To> Coerce<HashSet<To>> for HashSet<From>
where From: CoerceKey<To>,

source§

impl<From, To: ?Sized> Coerce<Box<To>> for Box<From>
where From: Coerce<To> + ?Sized,

source§

impl<From: Coerce<To>, To, const N: usize> Coerce<[To; N]> for [From; N]

source§

impl<FromK, FromV, ToK, ToV> Coerce<HashMap<ToK, ToV>> for HashMap<FromK, FromV>
where FromK: CoerceKey<ToK>, FromV: Coerce<ToV>,

Implementors§

source§

impl Coerce<[FrozenValue]> for FrozenTupleRef

source§

impl<'v> Coerce<Value<'v>> for FrozenValue

source§

impl<'v> Coerce<Value<'v>> for Value<'v>

source§

impl<'v> Coerce<ValueTyped<'v, StarlarkStr>> for FrozenStringValue

source§

impl<'v> Coerce<[Value<'v>]> for ListRef<'v>

source§

impl<'v> Coerce<[Value<'v>]> for TupleRef<'v>

source§

impl<'v, T: StarlarkValue<'v>> Coerce<FrozenValueTyped<'v, T>> for FrozenValueTyped<'v, T>

source§

impl<'v, T: StarlarkValue<'v>> Coerce<Value<'v>> for FrozenValueTyped<'v, T>

source§

impl<'v, T: StarlarkValue<'v>> Coerce<Value<'v>> for ValueTyped<'v, T>

source§

impl<'v, T: StarlarkValue<'v>> Coerce<ValueTyped<'v, T>> for ValueTyped<'v, T>

source§

impl<From: Coerce<To>, To> Coerce<ParametersSpec<To>> for ParametersSpec<From>

source§

impl<FromK, FromV, ToK, ToV> Coerce<SmallMap<ToK, ToV>> for SmallMap<FromK, FromV>
where FromK: CoerceKey<ToK>, FromV: Coerce<ToV>,

source§

impl<FromV, ToV> Coerce<TypeCompiled<ToV>> for TypeCompiled<FromV>
where FromV: Coerce<ToV>,