mithril_dmq/model/
network.rs

1use serde::{Deserialize, Serialize};
2use std::fmt::Display;
3use thiserror::Error;
4
5use mithril_common::MagicId;
6
7#[derive(Error, Debug)]
8pub enum DmqNetworkError {
9    #[error("parse from code error: '{0}'")]
10    ParseFromCode(String),
11}
12
13/// The Dmq Network that is being targeted
14#[allow(clippy::enum_variant_names)]
15#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize, Hash, Eq, PartialOrd)]
16pub enum DmqNetwork {
17    /// The Dmq mainnet network
18    MainNet,
19
20    /// A Dmq test network (preview, preprod or private testnet)
21    TestNet(MagicId),
22}
23
24impl DmqNetwork {
25    /// Mainnet magic ID
26    pub const MAINNET_MAGIC_ID: MagicId = 123; // TODO: Update magic ids for networks
27    /// Preprod magic ID
28    pub const PREPROD_MAGIC_ID: MagicId = 1; // TODO: Update magic ids for networks
29    /// Preview magic ID
30    pub const PREVIEW_MAGIC_ID: MagicId = 2; // TODO: Update magic ids for networks
31    /// Devnet magic ID
32    pub(crate) const DEVNET_MAGIC_ID: MagicId = 3141592; // TODO: Update magic ids for networks
33
34    /// Instantiates a DmqNetwork from its code and magic id
35    pub fn from_code(
36        network_code: String,
37        network_magic: Option<u64>,
38    ) -> Result<DmqNetwork, DmqNetworkError> {
39        match network_code.to_lowercase().as_str() {
40            "mainnet" => Ok(DmqNetwork::MainNet),
41            "preview" => Ok(DmqNetwork::TestNet(Self::PREVIEW_MAGIC_ID)),
42            "preprod" => Ok(DmqNetwork::TestNet(Self::PREPROD_MAGIC_ID)),
43            "devnet" => Ok(DmqNetwork::TestNet(Self::DEVNET_MAGIC_ID)),
44            "private" => {
45                if let Some(magic) = network_magic {
46                    Ok(DmqNetwork::TestNet(magic))
47                } else {
48                    Err(DmqNetworkError::ParseFromCode(
49                        "no NETWORK MAGIC number given for test network".to_string(),
50                    ))
51                }
52            }
53            what => Err(DmqNetworkError::ParseFromCode(format!(
54                "could not parse network '{what}', the only recognized networks are: mainnet, devnet, testnet, preview, preprod and private"
55            ))),
56        }
57    }
58
59    /// Returns the magic ID of the network
60    pub fn magic_id(&self) -> MagicId {
61        match *self {
62            DmqNetwork::MainNet => Self::MAINNET_MAGIC_ID,
63            DmqNetwork::TestNet(magic_id) => magic_id,
64        }
65    }
66}
67
68impl Display for DmqNetwork {
69    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70        match *self {
71            DmqNetwork::MainNet => write!(f, "mainnet"),
72            DmqNetwork::TestNet(magic_id) => match magic_id {
73                Self::PREVIEW_MAGIC_ID => write!(f, "preview"),
74                Self::PREPROD_MAGIC_ID => write!(f, "preprod"),
75                Self::DEVNET_MAGIC_ID => write!(f, "devnet"),
76                _ => write!(f, "private"),
77            },
78        }
79    }
80}
81
82impl From<DmqNetwork> for String {
83    fn from(network: DmqNetwork) -> Self {
84        network.to_string()
85    }
86}
87
88impl From<&DmqNetwork> for String {
89    fn from(network: &DmqNetwork) -> Self {
90        network.to_string()
91    }
92}
93
94impl From<MagicId> for DmqNetwork {
95    fn from(magic_id: MagicId) -> Self {
96        match magic_id {
97            Self::MAINNET_MAGIC_ID => Self::MainNet,
98            _ => Self::TestNet(magic_id),
99        }
100    }
101}
102
103#[cfg(test)]
104mod tests {
105    use super::*;
106
107    #[test]
108    fn test_dmq_network_from_code() {
109        assert_eq!(
110            DmqNetwork::from_code("mainnet".to_string(), None).unwrap(),
111            DmqNetwork::MainNet
112        );
113        assert_eq!(
114            DmqNetwork::from_code("mainnet".to_string(), Some(123)).unwrap(),
115            DmqNetwork::MainNet
116        );
117        assert_eq!(
118            DmqNetwork::from_code("preview".to_string(), None).unwrap(),
119            DmqNetwork::TestNet(DmqNetwork::PREVIEW_MAGIC_ID)
120        );
121        assert_eq!(
122            DmqNetwork::from_code("preview".to_string(), Some(123)).unwrap(),
123            DmqNetwork::TestNet(DmqNetwork::PREVIEW_MAGIC_ID)
124        );
125        assert_eq!(
126            DmqNetwork::from_code("preprod".to_string(), None).unwrap(),
127            DmqNetwork::TestNet(DmqNetwork::PREPROD_MAGIC_ID)
128        );
129        assert_eq!(
130            DmqNetwork::from_code("preprod".to_string(), Some(123)).unwrap(),
131            DmqNetwork::TestNet(DmqNetwork::PREPROD_MAGIC_ID)
132        );
133        assert_eq!(
134            DmqNetwork::from_code("devnet".to_string(), None).unwrap(),
135            DmqNetwork::TestNet(DmqNetwork::DEVNET_MAGIC_ID)
136        );
137        assert_eq!(
138            DmqNetwork::from_code("devnet".to_string(), Some(123)).unwrap(),
139            DmqNetwork::TestNet(DmqNetwork::DEVNET_MAGIC_ID)
140        );
141        assert_eq!(
142            DmqNetwork::from_code("private".to_string(), Some(123)).unwrap(),
143            DmqNetwork::TestNet(123)
144        );
145        assert!(DmqNetwork::from_code("private".to_string(), None).is_err());
146    }
147
148    #[test]
149    fn network_to_string() {
150        fn assert_all_conversions_eq(network: DmqNetwork, expected: &str) {
151            assert_eq!(network.to_string(), expected);
152            assert_eq!(String::from(network), expected);
153            assert_eq!(String::from(&network), expected);
154        }
155
156        assert_all_conversions_eq(DmqNetwork::MainNet, "mainnet");
157        assert_all_conversions_eq(DmqNetwork::TestNet(DmqNetwork::DEVNET_MAGIC_ID), "devnet");
158        assert_all_conversions_eq(DmqNetwork::TestNet(DmqNetwork::PREVIEW_MAGIC_ID), "preview");
159        assert_all_conversions_eq(DmqNetwork::TestNet(DmqNetwork::PREPROD_MAGIC_ID), "preprod");
160        assert_all_conversions_eq(DmqNetwork::TestNet(123456), "private");
161    }
162
163    #[test]
164    fn dmq_network_from_magic_id_roundtrip() {
165        fn assert_magic_id_conversion_roundtrip(magic_id: MagicId, expected: DmqNetwork) {
166            let network = DmqNetwork::from(magic_id);
167            assert_eq!(network, expected);
168            assert_eq!(network.magic_id(), magic_id);
169        }
170
171        assert_magic_id_conversion_roundtrip(DmqNetwork::MAINNET_MAGIC_ID, DmqNetwork::MainNet);
172        assert_magic_id_conversion_roundtrip(
173            DmqNetwork::PREVIEW_MAGIC_ID,
174            DmqNetwork::TestNet(DmqNetwork::PREVIEW_MAGIC_ID),
175        );
176        assert_magic_id_conversion_roundtrip(
177            DmqNetwork::PREPROD_MAGIC_ID,
178            DmqNetwork::TestNet(DmqNetwork::PREPROD_MAGIC_ID),
179        );
180        assert_magic_id_conversion_roundtrip(
181            DmqNetwork::DEVNET_MAGIC_ID,
182            DmqNetwork::TestNet(DmqNetwork::DEVNET_MAGIC_ID),
183        );
184        assert_magic_id_conversion_roundtrip(123456, DmqNetwork::TestNet(123456));
185    }
186}