use alloc::boxed::Box;
use alloc::str::FromStr;
use alloc::string::ToString;
use bech32::Hrp;
use crate::errors::NetworkIdError;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum NetworkId {
Mainnet,
Testnet,
Devnet,
Custom(Box<CustomNetworkId>),
}
impl NetworkId {
const MAINNET: &str = "mm";
const TESTNET: &str = "mtst";
const DEVNET: &str = "mdev";
pub fn new(string: &str) -> Result<Self, NetworkIdError> {
Hrp::parse(string)
.map(Self::from_hrp)
.map_err(|source| NetworkIdError::NetworkIdParseError(source.to_string().into()))
}
pub(crate) fn from_hrp(hrp: Hrp) -> Self {
match hrp.as_str() {
NetworkId::MAINNET => NetworkId::Mainnet,
NetworkId::TESTNET => NetworkId::Testnet,
NetworkId::DEVNET => NetworkId::Devnet,
_ => NetworkId::Custom(Box::new(CustomNetworkId::from_hrp(hrp))),
}
}
pub(crate) fn into_hrp(self) -> Hrp {
match self {
NetworkId::Mainnet => {
Hrp::parse(NetworkId::MAINNET).expect("mainnet hrp should be valid")
},
NetworkId::Testnet => {
Hrp::parse(NetworkId::TESTNET).expect("testnet hrp should be valid")
},
NetworkId::Devnet => Hrp::parse(NetworkId::DEVNET).expect("devnet hrp should be valid"),
NetworkId::Custom(custom) => custom.as_hrp(),
}
}
pub fn as_str(&self) -> &str {
match self {
NetworkId::Mainnet => NetworkId::MAINNET,
NetworkId::Testnet => NetworkId::TESTNET,
NetworkId::Devnet => NetworkId::DEVNET,
NetworkId::Custom(custom) => custom.as_str(),
}
}
pub fn is_mainnet(&self) -> bool {
matches!(self, NetworkId::Mainnet)
}
pub fn is_testnet(&self) -> bool {
matches!(self, NetworkId::Testnet)
}
pub fn is_devnet(&self) -> bool {
matches!(self, NetworkId::Devnet)
}
}
impl FromStr for NetworkId {
type Err = NetworkIdError;
fn from_str(string: &str) -> Result<Self, Self::Err> {
Self::new(string)
}
}
impl core::fmt::Display for NetworkId {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CustomNetworkId {
hrp: Hrp,
}
impl CustomNetworkId {
pub(crate) fn from_hrp(hrp: Hrp) -> Self {
CustomNetworkId { hrp }
}
pub(crate) fn as_hrp(&self) -> Hrp {
self.hrp
}
pub fn as_str(&self) -> &str {
self.hrp.as_str()
}
}
impl FromStr for CustomNetworkId {
type Err = NetworkIdError;
fn from_str(hrp_str: &str) -> Result<Self, Self::Err> {
Ok(CustomNetworkId {
hrp: Hrp::parse(hrp_str)
.map_err(|source| NetworkIdError::NetworkIdParseError(source.to_string().into()))?,
})
}
}
impl core::fmt::Display for CustomNetworkId {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(self.as_str())
}
}