apimock_config/config/
service_config.rs1use apimock_routing::{RuleSet, Strategy};
20use console::style;
21use serde::Deserialize;
22use util::canonicalized_fallback_respond_dir_to_print;
23
24use std::path::Path;
25
26mod util;
27
28use super::constant::{PRINT_DELIMITER, SERVICE_DEFAULT_FALLBACK_RESPOND_DIR};
29
30#[derive(Clone, Deserialize)]
31pub struct ServiceConfig {
32 pub strategy: Option<Strategy>,
35
36 #[serde(rename = "rule_sets")]
39 pub rule_sets_file_paths: Option<Vec<String>>,
40
41 #[serde(skip)]
46 pub rule_sets: Vec<RuleSet>,
47
48 #[serde(rename = "middlewares")]
51 pub middlewares_file_paths: Option<Vec<String>>,
52
53 pub fallback_respond_dir: String,
55}
56
57impl ServiceConfig {
58 pub fn validate(&self) -> bool {
68 let rule_sets_validate = self.rule_sets
69 .iter()
70 .enumerate()
71 .all(|(rule_set_idx, rule_set)| {
72 let prefix_validate = rule_set.prefix.is_none()
73 || rule_set.prefix.as_ref().unwrap().validate(rule_set_idx);
74
75 let default_validate =
76 rule_set.default.is_none() || rule_set.default.as_ref().unwrap().validate();
77
78 let guard_validate =
79 rule_set.guard.is_none() || rule_set.guard.as_ref().unwrap().validate();
80
81 let dir_prefix = rule_set.dir_prefix();
82 let rules_validate = rule_set.rules.iter().enumerate().all(|(rule_idx, rule)| {
83 rule.when.validate(rule_idx, rule_set_idx)
84 && rule
85 .respond
86 .validate(dir_prefix.as_str(), rule_idx, rule_set_idx)
87 });
88
89 prefix_validate && default_validate && guard_validate && rules_validate
90 });
91 if !rule_sets_validate {
92 log::error!("something wrong in rule sets");
93 }
94
95 let fallback_respond_dir_validate = Path::new(self.fallback_respond_dir.as_str()).exists();
96 if !fallback_respond_dir_validate {
97 log::error!(
98 "{} fallback_respond_dir: {}",
99 style("invalid").red(),
100 self.fallback_respond_dir
101 );
102 }
103
104 rule_sets_validate && fallback_respond_dir_validate
105 }
106}
107
108impl Default for ServiceConfig {
109 fn default() -> Self {
110 ServiceConfig {
111 strategy: Some(Strategy::default()),
112 rule_sets_file_paths: None,
113 rule_sets: vec![],
114 middlewares_file_paths: None,
115 fallback_respond_dir: SERVICE_DEFAULT_FALLBACK_RESPOND_DIR.to_owned(),
116 }
117 }
118}
119
120impl std::fmt::Display for ServiceConfig {
121 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
122 let has_rule_sets = !self.rule_sets.is_empty();
123
124 if has_rule_sets {
125 let _ = writeln!(
126 f,
127 "[rule_sets.strategy] {}",
128 self.strategy.clone().unwrap_or_default()
129 );
130 let _ = writeln!(f, "");
131 }
132
133 for (idx, rule_set) in self.rule_sets.iter().enumerate() {
134 let _ = writeln!(
135 f,
136 "@ rule_set #{} ({})\n",
137 idx + 1,
138 style(rule_set.file_path.as_str()).green()
139 );
140 let _ = write!(f, "{}\n", rule_set);
141 }
142
143 if has_rule_sets {
144 let _ = writeln!(f, "{}", PRINT_DELIMITER);
145 }
146
147 let _ = writeln!(
148 f,
149 "[fallback_respond_dir] {}",
150 canonicalized_fallback_respond_dir_to_print(self.fallback_respond_dir.as_str())
151 );
152
153 Ok(())
154 }
155}