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())
}
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 {
pub key: MetaKey,
pub instances: u32,
pub destination_rule: DestinationRule,
pub state: Option<ServiceState>,
pub category: Option<u32>,
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
}
}