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)]
#[non_exhaustive]
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) -> Result<(), String> {
for (rule_set_idx, rule_set) in self.rule_sets.iter().enumerate() {
if let Some(prefix) = rule_set.prefix.as_ref()
&& !prefix.validate(rule_set.dir_prefix().as_str(), rule_set_idx)
{
return Err(format!("invalid prefix (rule set #{})", rule_set_idx + 1));
}
if let Some(default) = rule_set.default.as_ref()
&& !default.validate()
{
return Err(format!("invalid default (rule set #{})", rule_set_idx + 1));
}
if let Some(guard) = rule_set.guard.as_ref()
&& !guard.validate()
{
return Err(format!("invalid guard (rule set #{})", rule_set_idx + 1));
}
let dir_prefix = rule_set.dir_prefix();
for (rule_idx, rule) in rule_set.rules.iter().enumerate() {
rule.validate(dir_prefix.as_str(), rule_idx, rule_set_idx)?;
}
}
if !Path::new(self.fallback_respond_dir.as_str()).exists() {
return Err(format!(
"invalid fallback_respond_dir: {}",
self.fallback_respond_dir
));
}
Ok(())
}
}
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 _ = writeln!(f, "{}", 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(())
}
}