use crate::{
error::{Error, ErrorKind, Kind},
EncodeAsFields, EncodeAsType, Field,
};
use alloc::{string::ToString, vec::Vec};
use codec::Encode;
use scale_info::{PortableRegistry, TypeDef};
pub struct Variant<'a, Vals> {
pub name: &'a str,
pub fields: super::composite::Composite<Vals>,
}
impl<'a, Vals> EncodeAsType for Variant<'a, Vals>
where
Vals: ExactSizeIterator<Item = (Option<&'a str>, &'a dyn EncodeAsType)> + Clone,
{
fn encode_as_type_to(
&self,
type_id: u32,
types: &PortableRegistry,
out: &mut Vec<u8>,
) -> Result<(), Error> {
let type_id = super::find_single_entry_with_same_repr(type_id, types);
let ty = types
.resolve(type_id)
.ok_or_else(|| Error::new(ErrorKind::TypeNotFound(type_id)))?;
match &ty.type_def {
TypeDef::Variant(var) => {
let vars = &var.variants;
let Some(v) = vars.iter().find(|v| v.name == self.name) else {
return Err(Error::new(ErrorKind::CannotFindVariant { name: self.name.to_string(), expected: type_id }));
};
v.index.encode_to(out);
let mut fields = v
.fields
.iter()
.map(|f| Field::new(f.ty.id, f.name.as_deref()));
self.fields.encode_as_fields_to(&mut fields, types, out)
}
_ => Err(Error::new(ErrorKind::WrongShape {
actual: Kind::Str,
expected: type_id,
})),
}
}
}