Skip to content

Commit a502cd6

Browse files
committed
feat(dmq): add a 'DmqNetwork' model
1 parent 574b064 commit a502cd6

File tree

4 files changed

+190
-0
lines changed

4 files changed

+190
-0
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/mithril-dmq/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ serde = { workspace = true }
3232
serde_bytes = "0.11.17"
3333
slog = { workspace = true }
3434
slog-scope = "4.4.0"
35+
thiserror = { workspace = true }
3536
tokio = { workspace = true, features = ["sync","rt-multi-thread"] }
3637

3738
[dev-dependencies]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
mod builder;
22
mod message;
3+
mod network;
34
mod timestamp;
45

56
pub use builder::*;
67
pub use message::*;
8+
pub use network::*;
79
pub use timestamp::*;
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
use serde::{Deserialize, Serialize};
2+
use std::fmt::Display;
3+
use thiserror::Error;
4+
5+
use mithril_common::MagicId;
6+
7+
#[derive(Error, Debug)]
8+
pub 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)]
16+
pub 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+
24+
impl 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+
68+
impl 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+
82+
impl From<DmqNetwork> for String {
83+
fn from(network: DmqNetwork) -> Self {
84+
network.to_string()
85+
}
86+
}
87+
88+
impl From<&DmqNetwork> for String {
89+
fn from(network: &DmqNetwork) -> Self {
90+
network.to_string()
91+
}
92+
}
93+
94+
impl 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)]
104+
mod 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+
}

0 commit comments

Comments
 (0)