use derive_new::new;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use super::{HttpMethods, KeyValue, Service, NAMESPACE_ENDPOINT, RULES_ENDPOINT};
use crate::client::Context;
#[derive(new, Default, Debug, Clone)]
pub struct RuleService<T> {
client: T,
context: Context,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Rule {
pub name: String,
pub trigger: String,
pub action: String,
}
impl Rule {
fn body(namespace: String, rule: &Rule) -> Result<Value, serde_json::Error> {
let trigger = format!("/{}/{}/", namespace, rule.trigger);
let action = format!("/{}/{}/", namespace, rule.action);
serde_json::to_value(Rule {
name: rule.name.clone(),
trigger,
action,
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct RuleResponse {
#[serde(default)]
pub namespace: String,
#[serde(default)]
pub name: String,
#[serde(default)]
pub version: String,
#[serde(default)]
pub annotations: Vec<KeyValue>,
#[serde(default)]
pub status: String,
#[serde(default)]
pub trigger: Value,
#[serde(default)]
pub action: Value,
#[serde(default)]
pub publish: bool,
#[serde(default)]
pub updated: i64,
}
#[derive(new, Debug, Clone, Serialize, Deserialize, Default)]
pub struct RuleListOptions {
pub limit: i64,
pub skip: i64,
pub docs: bool,
}
impl RuleResponse {
fn set_status(state: String) -> Self {
Self {
status: state,
..Default::default()
}
}
}
impl<T> RuleService<T>
where
T: Service,
{
pub fn list(&self) -> Result<Vec<RuleResponse>, String> {
let url = format!(
"{}/api/v1/{}/{}/{}",
self.context.host(),
NAMESPACE_ENDPOINT,
self.context.namespace(),
RULES_ENDPOINT,
);
let auth = self.context.auth();
let user = auth.0;
let pass = auth.1;
let request = match self.client.new_request(
Some(HttpMethods::GET),
url.as_str(),
Some((user, pass)),
None,
) {
Ok(request) => request,
Err(error) => return Err(error),
};
match self.client.invoke_request(request) {
Ok(x) => match serde_json::from_value(x) {
Ok(rules) => Ok(rules),
Err(err) => Err(format!("Failed to deserailize Rules {}", err)),
},
Err(x) => Err(format!("Failed to fetch the list of Rules {}", x)),
}
}
pub fn insert(&self, rule: &Rule, overwrite: bool) -> Result<RuleResponse, String> {
let url = format!(
"{}/api/v1/{}/{}/{}/{}?overwrite={}",
self.context.host(),
NAMESPACE_ENDPOINT,
self.context.namespace(),
RULES_ENDPOINT,
rule.name,
overwrite
);
let auth = self.context.auth();
let user = auth.0;
let pass = auth.1;
let body = match Rule::body(self.context.namespace().to_string(), rule) {
Ok(body) => body,
Err(error) => return Err(format!("Failed deserailize body {}", error)),
};
let request = match self.client.new_request(
Some(HttpMethods::PUT),
url.as_str(),
Some((user, pass)),
Some(body),
) {
Ok(request) => request,
Err(error) => return Err(error),
};
match self.client.invoke_request(request) {
Ok(x) => match serde_json::from_value(x) {
Ok(actions) => Ok(actions),
Err(err) => Err(format!("Failed to deserailize rule {}", err)),
},
Err(x) => Err(format!("Failed to create rule {}", x)),
}
}
pub fn get(&self, rule_name: &str) -> Result<RuleResponse, String> {
let url = format!(
"{}/api/v1/{}/{}/{}/{}",
self.context.host(),
NAMESPACE_ENDPOINT,
self.context.namespace(),
RULES_ENDPOINT,
rule_name
);
let auth = self.context.auth();
let user = auth.0;
let pass = auth.1;
let request = match self.client.new_request(
Some(HttpMethods::GET),
url.as_str(),
Some((user, pass)),
None,
) {
Ok(request) => request,
Err(error) => return Err(error),
};
match self.client.invoke_request(request) {
Ok(x) => match serde_json::from_value(x) {
Ok(actions) => Ok(actions),
Err(err) => Err(format!("Failed to deserailize rule {}", err)),
},
Err(x) => Err(format!("Failed to get rule properties{}", x)),
}
}
pub fn delete(&self, rule_name: &str) -> Result<RuleResponse, String> {
let url = format!(
"{}/api/v1/{}/{}/{}/{}",
self.context.host(),
NAMESPACE_ENDPOINT,
self.context.namespace(),
RULES_ENDPOINT,
rule_name
);
let auth = self.context.auth();
let user = auth.0;
let pass = auth.1;
let request = match self.client.new_request(
Some(HttpMethods::PUT),
url.as_str(),
Some((user, pass)),
None,
) {
Ok(request) => request,
Err(error) => return Err(error),
};
match self.client.invoke_request(request) {
Ok(x) => match serde_json::from_value(x) {
Ok(actions) => Ok(actions),
Err(err) => Err(format!("Failed to deserailize rule {}", err)),
},
Err(x) => Err(format!("Failed to get rule properties{}", x)),
}
}
pub fn setstate(&self, rule_name: &str, state: &str) -> Result<RuleResponse, String> {
let state = state.to_lowercase();
if state != "active" && state != "inactive" {
Err("Invalid setstate options".to_string())
} else {
let url = format!(
"{}/api/v1/{}/{}/{}/{}",
self.context.host(),
NAMESPACE_ENDPOINT,
self.context.namespace(),
RULES_ENDPOINT,
rule_name
);
let auth = self.context.auth();
let user = auth.0;
let pass = auth.1;
let setstate = RuleResponse::set_status(state);
let body = match serde_json::to_value(setstate) {
Ok(body) => body,
Err(error) => return Err(format!("Failed deserailize body {}", error)),
};
let request = match self.client.new_request(
Some(HttpMethods::POST),
url.as_str(),
Some((user, pass)),
Some(body),
) {
Ok(request) => request,
Err(error) => return Err(error),
};
match self.client.invoke_request(request) {
Ok(x) => match serde_json::from_value(x) {
Ok(actions) => Ok(actions),
Err(err) => Err(format!("Failed to deserailize rule {}", err)),
},
Err(x) => Err(format!("Failed to SetState for Rule {}", x)),
}
}
}
}