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