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