distant_net/server/
config.rs

1use std::num::ParseFloatError;
2use std::str::FromStr;
3use std::time::Duration;
4
5use derive_more::{Display, Error};
6use serde::{Deserialize, Serialize};
7
8const DEFAULT_CONNECTION_SLEEP: Duration = Duration::from_millis(1);
9const DEFAULT_HEARTBEAT_DURATION: Duration = Duration::from_secs(5);
10
11/// Represents a general-purpose set of properties tied with a server instance
12#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
13pub struct ServerConfig {
14    /// Time to wait inbetween connection read/write when nothing was read or written on last pass
15    pub connection_sleep: Duration,
16
17    /// Minimum time to wait inbetween sending heartbeat messages
18    pub connection_heartbeat: Duration,
19
20    /// Rules for how a server will shutdown automatically
21    pub shutdown: Shutdown,
22}
23
24impl Default for ServerConfig {
25    fn default() -> Self {
26        Self {
27            connection_sleep: DEFAULT_CONNECTION_SLEEP,
28            connection_heartbeat: DEFAULT_HEARTBEAT_DURATION,
29            shutdown: Default::default(),
30        }
31    }
32}
33
34/// Rules for how a server will shut itself down automatically
35#[derive(Copy, Clone, Debug, Display, PartialEq, Eq)]
36pub enum Shutdown {
37    /// Server should shutdown immediately after duration exceeded
38    #[display(fmt = "after={}", "_0.as_secs_f32()")]
39    After(Duration),
40
41    /// Server should shutdown after no connections for over duration time
42    #[display(fmt = "lonely={}", "_0.as_secs_f32()")]
43    Lonely(Duration),
44
45    /// No shutdown logic will be applied to the server
46    #[display(fmt = "never")]
47    Never,
48}
49
50impl Shutdown {
51    /// Return duration associated with shutdown if it has one
52    pub fn duration(&self) -> Option<Duration> {
53        match self {
54            Self::Never => None,
55            Self::After(x) | Self::Lonely(x) => Some(*x),
56        }
57    }
58}
59
60impl Default for Shutdown {
61    /// By default, shutdown is never
62    fn default() -> Self {
63        Self::Never
64    }
65}
66
67/// Parsing errors that can occur for [`Shutdown`]
68#[derive(Clone, Debug, Display, Error, PartialEq, Eq)]
69pub enum ShutdownParseError {
70    #[display(fmt = "Bad value for after: {_0}")]
71    BadValueForAfter(ParseFloatError),
72
73    #[display(fmt = "Bad value for lonely: {_0}")]
74    BadValueForLonely(ParseFloatError),
75
76    #[display(fmt = "Missing key")]
77    MissingKey,
78
79    #[display(fmt = "Unknown key")]
80    UnknownKey,
81}
82
83impl FromStr for Shutdown {
84    type Err = ShutdownParseError;
85
86    fn from_str(s: &str) -> Result<Self, Self::Err> {
87        if s.eq_ignore_ascii_case("never") {
88            Ok(Self::Never)
89        } else {
90            let (left, right) = s.split_once('=').ok_or(ShutdownParseError::MissingKey)?;
91            let left = left.trim();
92            let right = right.trim();
93            if left.eq_ignore_ascii_case("after") {
94                Ok(Self::After(Duration::from_secs_f32(
95                    right
96                        .parse()
97                        .map_err(ShutdownParseError::BadValueForAfter)?,
98                )))
99            } else if left.eq_ignore_ascii_case("lonely") {
100                Ok(Self::Lonely(Duration::from_secs_f32(
101                    right
102                        .parse()
103                        .map_err(ShutdownParseError::BadValueForLonely)?,
104                )))
105            } else {
106                Err(ShutdownParseError::UnknownKey)
107            }
108        }
109    }
110}
111
112impl Serialize for Shutdown {
113    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
114    where
115        S: serde::ser::Serializer,
116    {
117        String::serialize(&self.to_string(), serializer)
118    }
119}
120
121impl<'de> Deserialize<'de> for Shutdown {
122    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
123    where
124        D: serde::de::Deserializer<'de>,
125    {
126        let s = String::deserialize(deserializer)?;
127        FromStr::from_str(&s).map_err(serde::de::Error::custom)
128    }
129}