confitdb 0.1.4

ConfitDB is an experimental, distributed, real-time database, giving full control on conflict resolution.
Documentation
use confitul::{ConfigCheck, ConfigCheckError};
use serde::{Deserialize, Serialize};

pub const DEFAULT_LISTEN_ADDR: &str = "0.0.0.0";
pub const DEFAULT_LISTEN_PORT: i16 = 8077;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServerOptions {
    pub listen_addr: String,
    pub listen_port: i16,
}

impl ServerOptions {
    pub fn new() -> ServerOptions {
        ServerOptions::default()
    }

    pub fn with_listen_addr(&self, listen_addr: &str) -> ServerOptions {
        match self.try_with_listen_addr(listen_addr) {
            Ok(updated) => updated,
            Err(_) => {
                let mut updated = self.clone();
                updated.listen_addr = DEFAULT_LISTEN_ADDR.to_string();
                updated
            }
        }
    }

    pub fn try_with_listen_addr(
        &self,
        listen_addr: &str,
    ) -> Result<ServerOptions, ConfigCheckError> {
        let mut updated = self.clone();
        updated.listen_addr = listen_addr.to_string();
        updated.check()?;
        Ok(updated)
    }

    pub fn with_listen_port(&self, listen_port: i16) -> ServerOptions {
        match self.try_with_listen_port(listen_port) {
            Ok(updated) => updated,
            Err(_) => {
                let mut updated = self.clone();
                updated.listen_port = DEFAULT_LISTEN_PORT;
                updated
            }
        }
    }

    pub fn try_with_listen_port(
        &self,
        listen_port: i16,
    ) -> Result<ServerOptions, ConfigCheckError> {
        let mut updated = self.clone();
        updated.listen_port = listen_port;
        updated.check()?;
        Ok(updated)
    }
}

impl ConfigCheck for ServerOptions {
    fn check(&self) -> Result<ServerOptions, ConfigCheckError> {
        // [TODO:check addr:port]
        Ok(self.clone())
    }
}

impl std::default::Default for ServerOptions {
    fn default() -> ServerOptions {
        ServerOptions {
            listen_addr: DEFAULT_LISTEN_ADDR.to_string(),
            listen_port: DEFAULT_LISTEN_PORT,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::ServerOptions;
    use serde_json;

    #[test]
    fn test_cloud_options_serde_json() {
        let options = ServerOptions::new();
        let serialized = serde_json::to_string(&options).unwrap();
        assert_eq!(
            "{\"listen_addr\":\"0.0.0.0\",\"listen_port\":8077}",
            serialized
        );
    }
}