canic_core/access/
rule.rs1use crate::{
2 Error, ThisError, access::AccessError, infra::network::Network,
3 ops::runtime::network::NetworkOps,
4};
5
6#[derive(Debug, ThisError)]
11pub enum RuleAccessError {
12 #[error("this endpoint requires a build-time network (DFX_NETWORK) of either 'ic' or 'local'")]
13 BuildNetworkUnknown,
14
15 #[error(
16 "this endpoint is only available when built for '{expected}' (DFX_NETWORK), but was built for '{actual}'"
17 )]
18 BuildNetworkMismatch { expected: Network, actual: Network },
19}
20
21impl From<RuleAccessError> for Error {
22 fn from(err: RuleAccessError) -> Self {
23 AccessError::Rule(err).into()
24 }
25}
26
27#[allow(clippy::unused_async)]
34pub async fn build_network_ic() -> Result<(), AccessError> {
35 check_build_network(Network::Ic).map_err(AccessError::from)
36}
37
38#[allow(clippy::unused_async)]
41pub async fn build_network_local() -> Result<(), AccessError> {
42 check_build_network(Network::Local).map_err(AccessError::from)
43}
44
45pub(crate) fn check_build_network(expected: Network) -> Result<(), RuleAccessError> {
50 let actual = NetworkOps::current_network();
51
52 match actual {
53 Some(actual) if actual == expected => Ok(()),
54 Some(actual) => Err(RuleAccessError::BuildNetworkMismatch { expected, actual }),
55 None => Err(RuleAccessError::BuildNetworkUnknown),
56 }
57}
58
59#[cfg(test)]
64mod tests {
65 use super::*;
66
67 fn check(expected: Network, actual: Option<Network>) -> Result<(), RuleAccessError> {
68 match actual {
70 Some(actual) if actual == expected => Ok(()),
71 Some(actual) => Err(RuleAccessError::BuildNetworkMismatch { expected, actual }),
72 None => Err(RuleAccessError::BuildNetworkUnknown),
73 }
74 }
75
76 #[test]
77 fn build_network_matches_expected() {
78 assert!(check(Network::Ic, Some(Network::Ic)).is_ok());
79 assert!(check(Network::Local, Some(Network::Local)).is_ok());
80 }
81
82 #[test]
83 fn build_network_mismatch_errors() {
84 let err = check(Network::Ic, Some(Network::Local)).unwrap_err();
85
86 match err {
87 RuleAccessError::BuildNetworkMismatch { expected, actual } => {
88 assert_eq!(expected, Network::Ic);
89 assert_eq!(actual, Network::Local);
90 }
91 RuleAccessError::BuildNetworkUnknown => panic!("expected BuildNetworkMismatch"),
92 }
93 }
94
95 #[test]
96 fn build_network_unknown_errors() {
97 let err = check(Network::Ic, None).unwrap_err();
98 assert!(matches!(err, RuleAccessError::BuildNetworkUnknown));
99 }
100}