use alloc::string::ToString;
use crate::errors::AssetError;
use crate::utils::serde::{
ByteReader,
ByteWriter,
Deserializable,
DeserializationError,
Serializable,
};
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
#[repr(u8)]
pub enum AssetComposition {
#[default]
None = Self::NONE,
Fungible = Self::FUNGIBLE,
Custom = Self::CUSTOM,
}
impl AssetComposition {
const NONE: u8 = 0;
const FUNGIBLE: u8 = 1;
const CUSTOM: u8 = 2;
pub const SERIALIZED_SIZE: usize = core::mem::size_of::<AssetComposition>();
pub const fn as_u8(&self) -> u8 {
*self as u8
}
pub const fn is_none(&self) -> bool {
matches!(self, Self::None)
}
pub const fn is_fungible(&self) -> bool {
matches!(self, Self::Fungible)
}
pub const fn is_custom(&self) -> bool {
matches!(self, Self::Custom)
}
}
impl TryFrom<u8> for AssetComposition {
type Error = AssetError;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
Self::NONE => Ok(Self::None),
Self::FUNGIBLE => Ok(Self::Fungible),
Self::CUSTOM => Ok(Self::Custom),
_ => Err(AssetError::UnknownAssetComposition(value)),
}
}
}
impl core::fmt::Display for AssetComposition {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let string = match self {
AssetComposition::None => "none",
AssetComposition::Fungible => "fungible",
AssetComposition::Custom => "custom",
};
f.write_str(string)
}
}
impl Serializable for AssetComposition {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
target.write_u8(self.as_u8());
}
fn get_size_hint(&self) -> usize {
AssetComposition::SERIALIZED_SIZE
}
}
impl Deserializable for AssetComposition {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
Self::try_from(source.read_u8()?)
.map_err(|err| DeserializationError::InvalidValue(err.to_string()))
}
}