63 lines
1.8 KiB
Rust
63 lines
1.8 KiB
Rust
|
use std::net::IpAddr;
|
||
|
|
||
|
use serde_derive::{Deserialize, Serialize};
|
||
|
|
||
|
type Version = u8;
|
||
|
const CONF_VERSION: Version = 0;
|
||
|
|
||
|
#[derive(Default, Debug, Serialize, Deserialize)]
|
||
|
pub struct Configuration {
|
||
|
/// The version of the configuration. This is a MAJOR configuration only;
|
||
|
/// it should be incremented whenever breaking changes to the configuration
|
||
|
/// are made.
|
||
|
pub version: Version,
|
||
|
/// The IP to listen on for incoming user datagrams (excluding port).
|
||
|
pub ip: String,
|
||
|
/// The port to listen on for incoming user datagrams.
|
||
|
pub port: u16,
|
||
|
}
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
pub enum ConfigurationError {
|
||
|
InvalidIp,
|
||
|
IncompatibleVersion(Version),
|
||
|
}
|
||
|
|
||
|
impl std::fmt::Display for ConfigurationError {
|
||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||
|
match self {
|
||
|
ConfigurationError::IncompatibleVersion(v) => write!(f,
|
||
|
"Expected configuration version {} but got version {}.",
|
||
|
CONF_VERSION, v),
|
||
|
ConfigurationError::InvalidIp => write!(f, "Invalid IP."),
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl std::error::Error for ConfigurationError {}
|
||
|
|
||
|
impl Configuration {
|
||
|
pub fn check(&self) -> Result<(), ConfigurationError> {
|
||
|
self.check_version()?;
|
||
|
self.check_ip()?;
|
||
|
// No need to check the port; any u16 is a valid port.
|
||
|
Ok(())
|
||
|
}
|
||
|
|
||
|
fn check_version(&self) -> Result<(), ConfigurationError> {
|
||
|
if self.version != CONF_VERSION {
|
||
|
Err(ConfigurationError::IncompatibleVersion(self.version))
|
||
|
} else {
|
||
|
Ok(())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn check_ip(&self) -> Result<(), ConfigurationError> {
|
||
|
if self.ip.parse::<std::net::IpAddr>().is_err() {
|
||
|
Err(ConfigurationError::InvalidIp)
|
||
|
} else {
|
||
|
Ok(())
|
||
|
}
|
||
|
}
|
||
|
}
|