confitul 0.1.4

ConfitUL contains utilities for ConfitDB which is an experimental, distributed, real-time database, giving full control on conflict resolution.
Documentation
use crate::config_check::{BadSizeError, ConfigCheck, ConfigCheckError};
use crate::local_host_options::LocalHostOptions;
use serde::{Deserialize, Serialize};

pub const DEFAULT_CLUSTER_SIZE: usize = 10;
pub const MIN_CLUSTER_SIZE: usize = 1;
pub const MAX_CLUSTER_SIZE: usize = 1000;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClusterOptions {
    pub size: usize,
    pub local_host: LocalHostOptions,
}

impl ClusterOptions {
    pub fn new(local_host_options: Option<LocalHostOptions>) -> ClusterOptions {
        let real_local_host_options = local_host_options.unwrap_or(LocalHostOptions::default());
        let mut cluster_options = Self::default();
        cluster_options.local_host = real_local_host_options;
        cluster_options
    }

    pub fn with_size(&self, size: usize) -> ClusterOptions {
        match self.try_with_size(size) {
            Ok(updated) => updated,
            Err(_) => {
                let mut updated = self.clone();
                updated.size = DEFAULT_CLUSTER_SIZE;
                updated
            }
        }
    }

    pub fn try_with_size(&self, size: usize) -> Result<ClusterOptions, ConfigCheckError> {
        let mut updated = self.clone();
        updated.size = size;
        updated.check()?;
        Ok(updated)
    }
}

impl ConfigCheck for ClusterOptions {
    fn check(&self) -> Result<ClusterOptions, ConfigCheckError> {
        match BadSizeError::check("size", self.size, MIN_CLUSTER_SIZE, MAX_CLUSTER_SIZE) {
            Ok(_) => {}
            Err(e) => return Err(e),
        }
        Ok(self.clone())
    }
}

impl std::default::Default for ClusterOptions {
    fn default() -> ClusterOptions {
        ClusterOptions {
            size: DEFAULT_CLUSTER_SIZE,
            local_host: LocalHostOptions::default(),
        }
    }
}

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

    #[test]
    fn test_cluster_options_serde_json() {
        let options = ClusterOptions::new(None);
        let serialized = serde_json::to_string(&options).unwrap();
        assert_eq!(
            format!(
                "{{\"size\":10,\"local_host\":{{\"name\":\"{}\",\"description\":\"\",\"urls\":[]}}}}",
                gethostname().to_str().unwrap()
            ),
            serialized
        );
    }
}