use crate::Address;
use alloc::vec::Vec;
use derive_more::{Deref, DerefMut, Display, IntoIterator};
use nonempty::NonEmpty;
use parity_scale_codec::{Decode, Encode};
use scale_info::{TypeInfo, build::Fields};
#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Deref, DerefMut, IntoIterator)]
pub struct ValidatorsVec(NonEmpty<Address>);
impl Encode for ValidatorsVec {
fn encode(&self) -> Vec<u8> {
Into::<Vec<_>>::into(self.0.clone()).encode()
}
}
impl Decode for ValidatorsVec {
fn decode<I: parity_scale_codec::Input>(
input: &mut I,
) -> Result<Self, parity_scale_codec::Error> {
let inner: Vec<Address> = Decode::decode(input)?;
NonEmpty::from_vec(inner)
.map(Self)
.ok_or(parity_scale_codec::Error::from(
"Failed to decode ValidatorsVec: empty vector",
))
}
}
impl TypeInfo for ValidatorsVec {
type Identity = Self;
fn type_info() -> scale_info::Type {
scale_info::Type::builder()
.path(scale_info::Path::new("ValidatorsVec", module_path!()))
.composite(Fields::unnamed().field(|f| f.ty::<Vec<Address>>()))
}
}
#[derive(Debug, Display)]
#[display("ValidatorsVec cannot be created from an empty collection")]
pub struct EmptyValidatorsError;
#[cfg(feature = "std")]
impl std::error::Error for EmptyValidatorsError {}
#[cfg(feature = "mock")]
impl FromIterator<Address> for ValidatorsVec {
#[track_caller]
fn from_iter<T: IntoIterator<Item = Address>>(iter: T) -> Self {
let vec: Vec<Address> = iter.into_iter().collect();
NonEmpty::from_vec(vec)
.map(ValidatorsVec)
.expect("ValidatorsVec cannot be created from an empty collection")
}
}
impl TryFrom<Vec<Address>> for ValidatorsVec {
type Error = EmptyValidatorsError;
fn try_from(value: Vec<Address>) -> Result<Self, Self::Error> {
NonEmpty::from_vec(value)
.map(Self)
.ok_or(EmptyValidatorsError)
}
}
impl TryFrom<Vec<alloy_primitives::Address>> for ValidatorsVec {
type Error = EmptyValidatorsError;
fn try_from(value: Vec<alloy_primitives::Address>) -> Result<Self, Self::Error> {
let vec: Vec<Address> = value.into_iter().map(Into::into).collect();
NonEmpty::from_vec(vec)
.map(Self)
.ok_or(EmptyValidatorsError)
}
}
impl From<NonEmpty<Address>> for ValidatorsVec {
fn from(value: NonEmpty<Address>) -> Self {
Self(value)
}
}
impl From<ValidatorsVec> for Vec<Address> {
fn from(value: ValidatorsVec) -> Self {
value.0.into()
}
}
impl From<ValidatorsVec> for Vec<gear_core::ids::ActorId> {
fn from(value: ValidatorsVec) -> Self {
value.into_iter().map(Address::into).collect()
}
}