apimock_routing/rule_set/rule/when/
request.rs1use console::style;
2use http_method::HttpMethod;
3use serde::Deserialize;
4
5mod body;
6mod headers;
7pub mod http_method;
8pub mod rule_op;
9pub mod url_path;
10mod util;
11
12use crate::parsed_request::ParsedRequest;
13use body::Body;
14use headers::Headers;
15use url_path::{UrlPath, UrlPathConfig};
16use util::fmt_condition_connector;
17
18#[derive(Clone, Deserialize, Debug)]
19pub struct Request {
20 #[serde(rename = "url_path")]
21 pub url_path_config: Option<UrlPathConfig>,
22 #[serde(skip)]
23 pub url_path: Option<UrlPath>,
24 #[serde(rename = "method")]
25 pub http_method: Option<HttpMethod>,
26 pub headers: Option<Headers>,
27 pub body: Option<Body>,
28}
29
30impl Request {
31 pub fn is_match(
33 &self,
34 parsed_request: &ParsedRequest,
35 rule_idx: usize,
36 rule_set_idx: usize,
37 ) -> bool {
38 let url_path_is_match = self.url_path.is_none()
39 || self
40 .url_path
41 .as_ref()
42 .unwrap()
43 .is_match(parsed_request.url_path.as_str());
44
45 let http_method_is_match = self.http_method.is_none()
46 || self
47 .http_method
48 .as_ref()
49 .unwrap()
50 .is_match(&parsed_request.component_parts.method);
51
52 let headers_is_match = self.headers.is_none()
53 || self.headers.as_ref().unwrap().is_match(
54 &parsed_request.component_parts.headers,
55 rule_idx,
56 rule_set_idx,
57 );
58
59 let body_is_match =
60 self.body.is_none() || self.body.as_ref().unwrap().is_match(&parsed_request);
61
62 url_path_is_match && http_method_is_match && headers_is_match && body_is_match
63 }
64
65 pub fn validate(&self, rule_idx: usize, rule_set_idx: usize) -> bool {
67 if self.url_path.is_none()
68 && self.http_method.is_none()
69 && self.headers.is_none()
70 && self.body.is_none()
71 {
72 log::error!(
73 "{} in when.request at least either of: url_path, method, headers or body (rule #{} in rule set #{})",
74 style("required").red(),
75 rule_idx + 1,
76 rule_set_idx + 1
77 );
78 return false;
79 }
80
81 let url_path_validate = match self.url_path.as_ref() {
82 Some(url_path) => url_path.validate(),
83 None => true,
84 };
85
86 let http_method_validate = true;
87
88 let headers_validate = match self.headers.as_ref() {
89 Some(headers) => {
90 let ret = headers.validate();
91 if !ret {
92 log::error!(
93 "something wrong in headers (rule #{} in rule set #{})",
94 rule_idx + 1,
95 rule_set_idx + 1
96 )
97 }
98 ret
99 }
100 None => true,
101 };
102
103 let body_validate = match self.body.as_ref() {
104 Some(body) => {
105 let ret = body.validate();
106 if !ret {
107 log::error!(
108 "something wrong in body (rule #{} in rule set #{})",
109 rule_idx + 1,
110 rule_set_idx + 1
111 )
112 }
113 ret
114 }
115 None => true,
116 };
117
118 url_path_validate && http_method_validate && headers_validate && body_validate
119 }
120}
121
122impl std::fmt::Display for Request {
123 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
124 let mut s: Vec<String> = vec![];
125
126 if let Some(x) = self.url_path_config.as_ref() {
127 s.push(format!("{}", x));
128 }
129 if let Some(x) = self.http_method.as_ref() {
130 s.push(format!("{}", x));
131 }
132 if let Some(x) = self.headers.as_ref() {
133 s.push(format!("{}", x));
134 }
135 if let Some(x) = self.body.as_ref() {
136 s.push(format!("{}", x));
137 }
138
139 let _ = write!(f, "{} ", s.join(fmt_condition_connector().as_str()));
140 Ok(())
141 }
142}