use apimock_routing::{RuleSet, Strategy};
use console::style;
use serde::Deserialize;
use util::canonicalized_fallback_respond_dir_to_print;
use std::path::Path;
mod util;
use super::constant::{PRINT_DELIMITER, SERVICE_DEFAULT_FALLBACK_RESPOND_DIR};
#[derive(Clone, Deserialize)]
pub struct ServiceConfig {
pub strategy: Option<Strategy>,
#[serde(rename = "rule_sets")]
pub rule_sets_file_paths: Option<Vec<String>>,
#[serde(skip)]
pub rule_sets: Vec<RuleSet>,
#[serde(rename = "middlewares")]
pub middlewares_file_paths: Option<Vec<String>>,
pub fallback_respond_dir: String,
}
impl ServiceConfig {
pub fn validate(&self) -> bool {
let rule_sets_validate = self.rule_sets
.iter()
.enumerate()
.all(|(rule_set_idx, rule_set)| {
let prefix_validate = rule_set.prefix.is_none()
|| rule_set.prefix.as_ref().unwrap().validate(rule_set_idx);
let default_validate =
rule_set.default.is_none() || rule_set.default.as_ref().unwrap().validate();
let guard_validate =
rule_set.guard.is_none() || rule_set.guard.as_ref().unwrap().validate();
let dir_prefix = rule_set.dir_prefix();
let rules_validate = rule_set.rules.iter().enumerate().all(|(rule_idx, rule)| {
rule.when.validate(rule_idx, rule_set_idx)
&& rule
.respond
.validate(dir_prefix.as_str(), rule_idx, rule_set_idx)
});
prefix_validate && default_validate && guard_validate && rules_validate
});
if !rule_sets_validate {
log::error!("something wrong in rule sets");
}
let fallback_respond_dir_validate = Path::new(self.fallback_respond_dir.as_str()).exists();
if !fallback_respond_dir_validate {
log::error!(
"{} fallback_respond_dir: {}",
style("invalid").red(),
self.fallback_respond_dir
);
}
rule_sets_validate && fallback_respond_dir_validate
}
}
impl Default for ServiceConfig {
fn default() -> Self {
ServiceConfig {
strategy: Some(Strategy::default()),
rule_sets_file_paths: None,
rule_sets: vec![],
middlewares_file_paths: None,
fallback_respond_dir: SERVICE_DEFAULT_FALLBACK_RESPOND_DIR.to_owned(),
}
}
}
impl std::fmt::Display for ServiceConfig {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let has_rule_sets = !self.rule_sets.is_empty();
if has_rule_sets {
let _ = writeln!(
f,
"[rule_sets.strategy] {}",
self.strategy.clone().unwrap_or_default()
);
let _ = writeln!(f, "");
}
for (idx, rule_set) in self.rule_sets.iter().enumerate() {
let _ = writeln!(
f,
"@ rule_set #{} ({})\n",
idx + 1,
style(rule_set.file_path.as_str()).green()
);
let _ = write!(f, "{}\n", rule_set);
}
if has_rule_sets {
let _ = writeln!(f, "{}", PRINT_DELIMITER);
}
let _ = writeln!(
f,
"[fallback_respond_dir] {}",
canonicalized_fallback_respond_dir_to_print(self.fallback_respond_dir.as_str())
);
Ok(())
}
}