Skip to main content

shardline_server/
server_role.rs

1use thiserror::Error;
2
3/// Runtime server role selection.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum ServerRole {
6    /// Serve both control-plane and transfer routes from one process.
7    All,
8    /// Serve control-plane and metadata routes only.
9    Api,
10    /// Serve large upload and download routes only.
11    Transfer,
12}
13
14impl ServerRole {
15    /// Parses a role token.
16    ///
17    /// # Errors
18    ///
19    /// Returns [`ServerRoleParseError`] when the token is not a supported role.
20    pub fn parse(value: &str) -> Result<Self, ServerRoleParseError> {
21        match value {
22            "all" => Ok(Self::All),
23            "api" => Ok(Self::Api),
24            "transfer" => Ok(Self::Transfer),
25            _ => Err(ServerRoleParseError),
26        }
27    }
28
29    /// Returns the canonical role token.
30    #[must_use]
31    pub const fn as_str(self) -> &'static str {
32        match self {
33            Self::All => "all",
34            Self::Api => "api",
35            Self::Transfer => "transfer",
36        }
37    }
38
39    /// Returns whether this role serves metadata and control-plane routes.
40    #[must_use]
41    pub const fn serves_api(self) -> bool {
42        matches!(self, Self::All | Self::Api)
43    }
44
45    /// Returns whether this role serves large upload and download routes.
46    #[must_use]
47    pub const fn serves_transfer(self) -> bool {
48        matches!(self, Self::All | Self::Transfer)
49    }
50
51    /// Returns whether this role needs the reconstruction cache.
52    #[must_use]
53    pub const fn uses_reconstruction_cache(self) -> bool {
54        self.serves_api()
55    }
56}
57
58/// Invalid server role token.
59#[derive(Debug, Clone, Copy, Error, PartialEq, Eq)]
60#[error("invalid server role")]
61pub struct ServerRoleParseError;
62
63#[cfg(test)]
64mod tests {
65    use super::ServerRole;
66
67    #[test]
68    fn parses_supported_roles() {
69        assert_eq!(ServerRole::parse("all"), Ok(ServerRole::All));
70        assert_eq!(ServerRole::parse("api"), Ok(ServerRole::Api));
71        assert_eq!(ServerRole::parse("transfer"), Ok(ServerRole::Transfer));
72    }
73
74    #[test]
75    fn api_role_only_serves_control_plane_routes() {
76        assert!(ServerRole::Api.serves_api());
77        assert!(!ServerRole::Api.serves_transfer());
78        assert!(ServerRole::Api.uses_reconstruction_cache());
79    }
80
81    #[test]
82    fn transfer_role_only_serves_transfer_routes() {
83        assert!(!ServerRole::Transfer.serves_api());
84        assert!(ServerRole::Transfer.serves_transfer());
85        assert!(!ServerRole::Transfer.uses_reconstruction_cache());
86    }
87}