canic_core/infra/ic/
network.rs

1use std::fmt::{self, Display};
2
3///
4/// BuildNetwork
5/// Identifies the environment the canister believes it runs in.
6///
7
8#[derive(Clone, Copy, Debug, Eq, PartialEq)]
9pub enum BuildNetwork {
10    Ic,
11    Local,
12}
13
14impl BuildNetwork {
15    #[must_use]
16    pub const fn as_str(self) -> &'static str {
17        match self {
18            Self::Ic => "ic",
19            Self::Local => "local",
20        }
21    }
22}
23
24impl Display for BuildNetwork {
25    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26        f.write_str(self.as_str())
27    }
28}
29
30///
31/// NetworkInfra
32///
33
34pub struct NetworkInfra;
35
36impl NetworkInfra {
37    ///
38    /// build_network
39    /// Returns the network inferred at *build time* from `DFX_NETWORK`.
40    /// This value is baked into the Wasm and does not reflect runtime state.
41    ///
42    /// ChatGPT 5.2 Final, Precise Verdict
43    ///
44    /// ✅ Yes, this works exactly as you say
45    /// ✅ It is valid IC/Wasm code
46    /// ❌ It is not runtime detection
47    /// ⚠️ The danger is semantic, not technical
48    /// ✅ Safe if treated as a build-time constant
49    /// ❌ Dangerous if treated as authoritative runtime truth
50    ///
51
52    #[must_use]
53    pub fn build_network() -> Option<BuildNetwork> {
54        Self::build_network_from_dfx_network(option_env!("DFX_NETWORK"))
55    }
56
57    ///
58    /// build_network_from_dfx_network
59    /// Pure helper for `build_network()`
60    ///
61
62    #[must_use]
63    pub fn build_network_from_dfx_network(
64        dfx_network: Option<&'static str>,
65    ) -> Option<BuildNetwork> {
66        match dfx_network {
67            Some("local") => Some(BuildNetwork::Local),
68            Some("ic") => Some(BuildNetwork::Ic),
69
70            _ => None,
71        }
72    }
73}
74
75///
76/// TESTS
77///
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82
83    #[test]
84    fn build_network_from_dfx_network_parses_ic() {
85        assert_eq!(
86            NetworkInfra::build_network_from_dfx_network(Some("ic")),
87            Some(BuildNetwork::Ic)
88        );
89    }
90
91    #[test]
92    fn build_network_from_dfx_network_parses_local() {
93        assert_eq!(
94            NetworkInfra::build_network_from_dfx_network(Some("local")),
95            Some(BuildNetwork::Local)
96        );
97    }
98
99    #[test]
100    fn build_network_from_dfx_network_rejects_unknown() {
101        assert_eq!(
102            NetworkInfra::build_network_from_dfx_network(Some("nope")),
103            None
104        );
105    }
106
107    #[test]
108    fn build_network_from_dfx_network_handles_missing() {
109        assert_eq!(NetworkInfra::build_network_from_dfx_network(None), None);
110    }
111}