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: Option<String>,
}
impl MetaKey {
pub fn new(name: String, ns: Option<String>) -> Self {
assert_ne!(name, "");
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())
}
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 {
None
} else {
Some(v2[0].to_string())
},
})
}
fn ns(&self) -> String {
self.ns
.as_ref()
.and_then(|s| Some(s.clone().add("-meta")))
.unwrap_or("meta".to_string())
}
}
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 {
pub key: MetaKey,
pub instances: u32,
pub destination_rule: DestinationRule,
pub state: Option<ServiceState>,
pub category: Option<u32>,
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,
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 extend(mut self, extend: Option<String>) -> Self {
self.extend = extend;
self
}
}