detector/
service.rs

1use serde::{Deserialize, Serialize};
2use std::ops::Add;
3
4#[derive(Copy, Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
5pub enum ServiceState {
6    /// 状态服
7    Stateful,
8    /// 无状态服
9    Stateless,
10}
11
12impl ServiceState {
13    pub fn stateful(&self) -> bool {
14        match self {
15            ServiceState::Stateless => false,
16            ServiceState::Stateful => true,
17        }
18    }
19
20    pub fn stateless(&self) -> bool {
21        !self.stateful()
22    }
23}
24
25#[derive(Clone, Debug, Serialize, Deserialize)]
26pub struct ServiceKey {
27    /// 服务实例唯一id
28    pub id: Option<u32>,
29    /// 服务名字
30    pub name: String,
31    /// 命名空间
32    pub ns: Option<String>,
33}
34
35impl ServiceKey {
36    pub fn new(name: String, ns: Option<String>) -> Self {
37        assert_ne!(name, "");
38        ServiceKey { id: None, name, ns }
39    }
40
41    pub fn id(&self) -> Option<u32> {
42        self.id
43    }
44
45    pub fn has_id(&self) -> bool {
46        self.id.is_some()
47    }
48
49    /// 路径
50    pub fn path(&self) -> Option<String> {
51        let id = self.id?;
52        Some(self.path_with_id(id))
53    }
54
55    /// 组成一个路径
56    pub fn path_with_id(&self, id: u32) -> String {
57        self.path_fn(id, |sk| {
58            format!("/{}/{}/{}", sk.ns(), sk.name, sk.id.unwrap())
59        })
60    }
61
62    pub fn path_fn(&self, id: u32, f: fn(ServiceKey) -> String) -> String {
63        let mut sk = self.clone();
64        sk.id = Some(id);
65        f(sk)
66    }
67
68    /// 父路径
69    pub fn parent_path(&self) -> String {
70        self.parent_path_fn(|sk| format!("/{}/{}/", sk.ns(), sk.name))
71    }
72
73    pub fn parent_path_fn(&self, f: fn(ServiceKey) -> String) -> String {
74        f(self.clone())
75    }
76
77    /// 根路径
78    pub fn root_path(&self) -> String {
79        self.root_fn(|sk| format!("/{}/", sk.ns()))
80    }
81
82    pub fn root_fn(&self, f: fn(ServiceKey) -> String) -> String {
83        f(self.clone())
84    }
85
86    /// 格式:/{ns}/{name}/{id}
87    pub fn parse(value: &str) -> Result<ServiceKey, ()> {
88        let v: Vec<&str> = value.trim().trim_start_matches('/').split('/').collect();
89        if v.len() != 3 {
90            return Err(());
91        }
92
93        let id = v[2].parse::<u32>().map_err(|_| ())?;
94        let v2: Vec<&str> = v[0].split('-').collect();
95
96        Ok(ServiceKey {
97            id: Some(id),
98            name: v[1].to_string(),
99            ns: if v2.len() == 1 {
100                None
101            } else {
102                Some(v2[0].to_string())
103            },
104        })
105    }
106
107    fn ns(&self) -> String {
108        self.ns
109            .clone()
110            .and_then(|s| Some(s.add("-service")))
111            .unwrap_or("service".to_string())
112    }
113}
114
115impl TryFrom<String> for ServiceKey {
116    type Error = String;
117    fn try_from(value: String) -> Result<Self, Self::Error> {
118        ServiceKey::parse(&value).map_err(|_| value)
119    }
120}
121
122impl<'a> TryFrom<&'a str> for ServiceKey {
123    type Error = &'a str;
124    fn try_from(value: &'a str) -> Result<Self, Self::Error> {
125        ServiceKey::parse(value).map_err(|_| value)
126    }
127}
128
129impl<'a> TryFrom<&'a [u8]> for ServiceKey {
130    type Error = &'a [u8];
131    fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
132        let v = std::str::from_utf8(value).map_err(|_| value)?;
133        ServiceKey::parse(v).map_err(|_| value)
134    }
135}
136
137#[derive(Clone, Debug, Serialize, Deserialize)]
138pub struct Service {
139    /// key
140    pub key: ServiceKey,
141    /// ttl时间, 秒数
142    pub ttl: Option<i64>,
143    /// 服务地址
144    pub ip: Option<String>,
145    /// 服务端口
146    pub port: Option<u16>,
147    /// 状态类型
148    pub state: Option<ServiceState>,
149    /// 服务类别
150    pub category: Option<u32>,
151    /// 扩展
152    pub extend: Option<String>,
153    /// 版本, 只读的
154    #[serde(skip)]
155    pub revision: Option<i64>,
156}
157
158impl Service {
159    pub fn from_key(key: ServiceKey) -> Self {
160        Self {
161            key,
162            ttl: None,
163            ip: None,
164            port: None,
165            state: None,
166            category: None,
167            extend: None,
168            revision: None,
169        }
170    }
171
172    pub fn address(&self) -> String {
173        if self.ip.is_none() {
174            return String::new();
175        } else if self.port.is_none() {
176            return self.ip.as_ref().unwrap().clone();
177        } else {
178            format!(
179                "{}:{}",
180                self.ip.as_ref().unwrap(),
181                self.port.as_ref().unwrap()
182            )
183        }
184    }
185
186    pub fn ttl(mut self, ttl: Option<i64>) -> Self {
187        self.ttl = ttl;
188        self
189    }
190
191    pub fn ip(mut self, ip: Option<String>) -> Self {
192        self.ip = ip;
193        self
194    }
195
196    pub fn port(mut self, port: Option<u16>) -> Self {
197        self.port = port;
198        self
199    }
200
201    pub fn state(mut self, state: Option<ServiceState>) -> Self {
202        self.state = state;
203        self
204    }
205
206    pub fn category(mut self, category: Option<u32>) -> Self {
207        self.category = category;
208        self
209    }
210
211    pub fn extend(mut self, extend: Option<String>) -> Self {
212        self.extend = extend;
213        self
214    }
215}
216
217#[derive(Clone, Debug)]
218pub struct Services {
219    /// 服务实例列表
220    pub services: Vec<Service>,
221}
222
223impl Services {
224    pub fn new() -> Services {
225        Services { services: vec![] }
226    }
227}
228
229/// 服务状态
230#[derive(Copy, Clone, Debug, Eq, PartialEq)]
231pub enum ServiceStatus {
232    /// 已注册
233    Registered = 0,
234    /// 未注册
235    Unregistered = 1,
236}
237
238impl ServiceStatus {
239    pub fn registered(&self) -> bool {
240        match self {
241            ServiceStatus::Registered => true,
242            ServiceStatus::Unregistered => false,
243        }
244    }
245
246    pub fn unregistered(&self) -> bool {
247        !self.registered()
248    }
249}
250
251impl From<u32> for ServiceStatus {
252    fn from(value: u32) -> Self {
253        match value {
254            0 => ServiceStatus::Registered,
255            1 => ServiceStatus::Unregistered,
256            _ => panic!("invalid value:{} for ServiceStatus", value),
257        }
258    }
259}