use super::composite::{Composite, CompositeField};
use crate::error::{Error, ErrorKind, Kind};
use alloc::{format, string::ToString, vec::Vec};
use codec::Encode;
use scale_type_resolver::{visitor, TypeResolver};
pub struct Variant<'a, R, Vals> {
pub name: &'a str,
pub fields: Composite<R, Vals>,
}
impl<'a, R, Vals> Variant<'a, R, Vals>
where
R: TypeResolver + 'a,
Vals: ExactSizeIterator<Item = (Option<&'a str>, CompositeField<'a, R>)> + Clone,
{
pub fn encode_variant_as_type(&self, type_id: R::TypeId, types: &R) -> Result<Vec<u8>, Error> {
let mut out = Vec::new();
self.encode_variant_as_type_to(type_id, types, &mut out)?;
Ok(out)
}
pub fn encode_variant_as_type_to(
&self,
type_id: R::TypeId,
types: &R,
out: &mut Vec<u8>,
) -> Result<(), Error> {
let type_id = super::find_single_entry_with_same_repr(type_id, types);
let v = visitor::new(type_id.clone(), |type_id, _| {
Err(Error::new(ErrorKind::WrongShape {
actual: Kind::Str,
expected_id: format!("{type_id:?}"),
}))
})
.visit_variant(|type_id, _, vars| {
let mut res = None;
for var in vars {
if var.name == self.name {
res = Some(var);
break;
}
}
let Some(mut var) = res else {
return Err(Error::new(ErrorKind::CannotFindVariant {
name: self.name.to_string(),
expected_id: format!("{type_id:?}"),
}));
};
var.index.encode_to(out);
self.fields
.encode_composite_fields_to(&mut var.fields, types, out)
});
super::resolve_type_and_encode(types, type_id, v)
}
}