Closed
Description
The below code demonstrates the problem. It is an attempt at doing a custom Encode
implementation of a complex type which takes advantage of the fact that the internals of the complex type are all compact-encodable.
use parity_scale_codec::{Encode, Decode, HasCompact, Compact, CompactAs};
#[derive(Default)]
struct Solution<V, T, W> {
votes1: Vec<(V, T)>,
votes2: Vec<(V, (T, W), T)>,
votes3: Vec<(V, [(T, W); 2usize], T)>,
}
#[derive(Default)]
struct BareSolution {
votes1: Vec<(u32, u16)>,
votes2: Vec<(u32, (u16, u64), u16)>,
votes3: Vec<(u32, [(u16, u64); 2usize], u16)>,
}
// This works fine
impl Encode for BareSolution {
fn encode(&self) -> Vec<u8> {
let mut r = vec![];
self.votes1
.iter()
.map(|(v, t)| (<Compact<u32>>::from(*v), <Compact<u16>>::from(*t)))
.for_each(|(v, t)| {
v.encode_to(&mut r);
t.encode_to(&mut r);
});
r
}
}
// This will not work.
impl<V: HasCompact + CompactAs + Copy, T: HasCompact + CompactAs + Copy, W: HasCompact + CompactAs + Copy> Encode for Solution<V, T, W> {
fn encode(&self) -> Vec<u8> {
let mut r = vec![];
self.votes1
.iter()
.map(|(v, t)| (Compact::from(*v), Compact::from(*t)))
.for_each(|(v, t)| {
// will not work because the compiler fails to identify `impl Encode` for `V`
// v.encode_to(&mut r);
// will trigger recursive derive error.
// <Compact<T> as Encode>::encode_to(&t, &mut r);
});
r
}
}
Looking at the code, it seems to be that <Comact<T> as Encode>
should work fine as long as T: HasCompact + CompactAs
, based on:
parity-scale-codec/src/compact.rs
Lines 108 to 111 in a54a3dd
and
parity-scale-codec/src/compact.rs
Lines 135 to 138 in a54a3dd
Albeit I might be missing something.
Metadata
Metadata
Assignees
Labels
No labels