detector 0.5.4

A set of types for service registration and discovery.
Documentation
use crate::status::ServiceState;
use crate::{DestinationRule, Strategy};
use serde::{Deserialize, Serialize};
use std::ops::Add;

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct MetaKey {
    /// 服务类型名字
    pub name: String,
    /// 命名空间
    pub ns: String,
}

impl MetaKey {
    pub fn new<S1: Into<String>, S2: Into<String>>(name: S1, ns: S2) -> Self {
        let name = name.into();
        assert_ne!(name.len(), 0);
        let ns = ns.into();
        MetaKey { name, ns }
    }

    pub fn path(&self) -> String {
        self.path_fn(|mk| format!("/{}/{}", mk.ns(), mk.name))
    }

    pub fn path_fn(&self, f: fn(MetaKey) -> String) -> String {
        let mk = self.clone();
        f(mk)
    }

    /// 根路径
    pub fn root_path(&self) -> String {
        self.root_fn(|mk| format!("/{}/", mk.ns()))
    }

    pub fn root_fn(&self, f: fn(MetaKey) -> String) -> String {
        f(self.clone())
    }

    /// 格式:/[{ns}-]meta/{name}
    pub fn parse(value: &str) -> Result<MetaKey, ()> {
        let v: Vec<&str> = value.trim().trim_start_matches('/').split('/').collect();
        if v.len() != 2 {
            return Err(());
        }

        let v2: Vec<&str> = v[0].split('-').collect();

        Ok(MetaKey {
            name: v[1].to_string(),
            ns: if v2.len() == 1 {
                String::new()
            } else {
                v2[0].to_string()
            },
        })
    }

    fn ns(&self) -> String {
        if self.ns.len() == 0 {
            "meta".to_string()
        } else {
            self.ns.clone().add("-meta")
        }
    }
}

impl TryFrom<String> for MetaKey {
    type Error = String;
    fn try_from(value: String) -> Result<Self, Self::Error> {
        MetaKey::parse(&value).map_err(|_| value)
    }
}

impl<'a> TryFrom<&'a str> for MetaKey {
    type Error = &'a str;
    fn try_from(value: &'a str) -> Result<Self, Self::Error> {
        MetaKey::parse(value).map_err(|_| value)
    }
}

impl<'a> TryFrom<&'a [u8]> for MetaKey {
    type Error = &'a [u8];
    fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
        let v = std::str::from_utf8(value).map_err(|_| value)?;
        MetaKey::parse(v).map_err(|_| value)
    }
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Meta {
    /// key
    pub key: MetaKey,
    /// 要部署的实例总数
    pub instances: u32,
    /// 转发规则
    pub destination_rule: DestinationRule,
    /// 状态类型
    pub state: Option<ServiceState>,
    /// 服务类别
    pub category: Option<u32>,
    /// 启用tls
    pub tls: Option<bool>,
    /// 带邮箱
    pub with_inbox: bool,
    /// 扩展
    pub extend: Option<String>,
    /// 版本, 只读的
    #[serde(skip)]
    pub revision: Option<i64>,
}

impl Meta {
    pub fn from_key(key: MetaKey) -> Self {
        Self::new(key, 0)
    }

    pub fn new(key: MetaKey, instances: u32) -> Self {
        Self {
            key,
            instances,
            destination_rule: DestinationRule::Path(Strategy::RoundRobin),
            extend: None,
            state: None,
            category: None,
            tls: None,
            with_inbox: true,
            revision: None,
        }
    }

    pub fn destination_rule(mut self, destination_rule: DestinationRule) -> Self {
        self.destination_rule = destination_rule;
        self
    }

    pub fn state(mut self, state: Option<ServiceState>) -> Self {
        self.state = state;
        self
    }

    pub fn category(mut self, category: Option<u32>) -> Self {
        self.category = category;
        self
    }

    pub fn tls(mut self, tls: Option<bool>) -> Self {
        self.tls = tls;
        self
    }
    
    pub fn extend<S: Into<String>>(mut self, extend: Option<S>) -> Self {
        self.extend = extend.map(|e|e.into());
        self
    }

    pub fn with_inbox(mut self, with_inbox: bool) -> Self {
        self.with_inbox = with_inbox;
        self
    }
}