use core::{
convert::TryFrom,
fmt::{self, Display, Formatter},
};
use crate::ApiError;
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum SystemContractType {
Mint,
ProofOfStake,
StandardPayment,
}
const MINT: &str = "mint";
pub const PROOF_OF_STAKE: &str = "proof of stake";
const STANDARD_PAYMENT: &str = "standard payment";
impl From<SystemContractType> for u32 {
fn from(system_contract_type: SystemContractType) -> u32 {
match system_contract_type {
SystemContractType::Mint => 0,
SystemContractType::ProofOfStake => 1,
SystemContractType::StandardPayment => 2,
}
}
}
#[doc(hidden)]
impl TryFrom<u32> for SystemContractType {
type Error = ApiError;
fn try_from(value: u32) -> Result<SystemContractType, Self::Error> {
match value {
0 => Ok(SystemContractType::Mint),
1 => Ok(SystemContractType::ProofOfStake),
2 => Ok(SystemContractType::StandardPayment),
_ => Err(ApiError::InvalidSystemContract),
}
}
}
impl Display for SystemContractType {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match *self {
SystemContractType::Mint => write!(f, "{}", MINT),
SystemContractType::ProofOfStake => write!(f, "{}", PROOF_OF_STAKE),
SystemContractType::StandardPayment => write!(f, "{}", STANDARD_PAYMENT),
}
}
}
#[cfg(test)]
mod tests {
use std::string::ToString;
use super::*;
#[test]
fn get_index_of_mint_contract() {
let index: u32 = SystemContractType::Mint.into();
assert_eq!(index, 0u32);
assert_eq!(SystemContractType::Mint.to_string(), MINT);
}
#[test]
fn get_index_of_pos_contract() {
let index: u32 = SystemContractType::ProofOfStake.into();
assert_eq!(index, 1u32);
assert_eq!(SystemContractType::ProofOfStake.to_string(), PROOF_OF_STAKE);
}
#[test]
fn get_index_of_standard_payment_contract() {
let index: u32 = SystemContractType::StandardPayment.into();
assert_eq!(index, 2u32);
assert_eq!(
SystemContractType::StandardPayment.to_string(),
STANDARD_PAYMENT
);
}
#[test]
fn create_mint_variant_from_int() {
let mint = SystemContractType::try_from(0).ok().unwrap();
assert_eq!(mint, SystemContractType::Mint);
}
#[test]
fn create_pos_variant_from_int() {
let pos = SystemContractType::try_from(1).ok().unwrap();
assert_eq!(pos, SystemContractType::ProofOfStake);
}
#[test]
fn create_standard_payment_variant_from_int() {
let pos = SystemContractType::try_from(2).ok().unwrap();
assert_eq!(pos, SystemContractType::StandardPayment);
}
#[test]
fn create_unknown_system_contract_variant() {
assert!(SystemContractType::try_from(3).is_err());
assert!(SystemContractType::try_from(4).is_err());
assert!(SystemContractType::try_from(10).is_err());
assert!(SystemContractType::try_from(u32::max_value()).is_err());
}
}