stubr/model/request/body/
eq_relaxed.rs1use crate::error::StubrResult;
2use crate::wiremock::{Match, Request};
3use crate::StubrError;
4use serde_json::Value;
5
6use super::{
7 diff::{all::RelaxedValue, array::RelaxedJsonArray, extra::RelaxedExtraJsonObj},
8 BodyMatcherStub,
9};
10
11pub struct JsonBodyRelaxedMatcher {
12 value: Value,
13 is_ignore_extra_elements: bool,
14 is_ignore_array_order: bool,
15}
16
17impl Match for JsonBodyRelaxedMatcher {
18 fn matches(&self, req: &Request) -> bool {
19 self.matching_relaxed_json(&req.body)
20 }
21}
22
23impl JsonBodyRelaxedMatcher {
24 pub fn matching_relaxed_json(&self, bytes: &[u8]) -> bool {
25 serde_json::from_slice::<Value>(bytes)
26 .ok()
27 .as_ref()
28 .map(|req_body| {
29 if self.is_ignore_extra_elements && self.is_ignore_array_order {
30 self.match_relaxed(req_body)
31 } else if self.is_ignore_extra_elements {
32 self.match_ignoring_extra(req_body)
33 } else {
34 self.match_ignoring_array_order(req_body)
35 }
36 })
37 .unwrap_or_default()
38 }
39
40 fn match_relaxed(&self, req_body: &Value) -> bool {
41 RelaxedValue(&self.value) == RelaxedValue(req_body)
42 }
43
44 fn match_ignoring_extra(&self, req_body: &Value) -> bool {
45 RelaxedExtraJsonObj(&self.value) == RelaxedExtraJsonObj(req_body)
46 }
47
48 fn match_ignoring_array_order(&self, req_body: &Value) -> bool {
49 RelaxedJsonArray(&self.value) == RelaxedJsonArray(req_body)
50 }
51}
52
53impl TryFrom<&BodyMatcherStub> for JsonBodyRelaxedMatcher {
54 type Error = StubrError;
55
56 fn try_from(body: &BodyMatcherStub) -> StubrResult<Self> {
57 body.equal_to_json
58 .as_ref()
59 .filter(|_| body.is_relaxed_matching())
60 .map(|v| Self {
61 value: v.to_owned(),
62 is_ignore_extra_elements: body.is_ignore_extra_elements(),
63 is_ignore_array_order: body.is_ignore_array_order(),
64 })
65 .ok_or_else(|| StubrError::QuietError)
66 }
67}