Trait frame_support::dispatch::EncodeLike
pub trait EncodeLike<T = Self>: Sized + Encodewhere
T: Encode,{ }
Expand description
A marker trait that tells the compiler that a type encode to the same representation as another type.
E.g. Vec<u8>
has the same encoded representation as &[u8]
.
Example
fn encode_like<T: Encode, R: EncodeLike<T>>(data: &R) {
data.encode(); // Valid `T` encoded value.
}
fn main() {
// Just pass the a reference to the normal tuple.
encode_like::<(u32, u32), _>(&(1u32, 2u32));
// Pass a tuple of references
encode_like::<(u32, u32), _>(&(&1u32, &2u32));
// Pass a tuple of a reference and a value.
encode_like::<(u32, u32), _>(&(&1u32, 2u32));
}
Warning
The relation is not symetric, T
implements EncodeLike<U>
does not mean U
has same
representation as T
.
For instance we could imaging a non zero integer to be encoded to the same representation as
the said integer but not the other way around.
Limitation
Not all possible implementations of EncodeLike are implemented (for instance Box<Box<u32>>
does not implement EncodeLike<u32>
). To bypass this issue either open a PR to add the new
combination or use Ref
reference wrapper or define your own wrapper
and implement EncodeLike
on it as such:
fn encode_like<T: Encode, R: EncodeLike<T>>(data: &R) {
data.encode(); // Valid `T` encoded value.
}
struct MyWrapper<'a>(&'a (Box<Box<u32>>, u32));
impl<'a> core::ops::Deref for MyWrapper<'a> { // Or use derive_deref crate
type Target = (Box<Box<u32>>, u32);
fn deref(&self) -> &Self::Target { &self.0 }
}
impl<'a> parity_scale_codec::WrapperTypeEncode for MyWrapper<'a> {}
impl<'a> parity_scale_codec::EncodeLike<(u32, u32)> for MyWrapper<'a> {}
fn main() {
let v = (Box::new(Box::new(0)), 0);
encode_like::<(u32, u32), _>(&MyWrapper(&v));
}