stubr/model/request/body/
eq_relaxed.rs

1use 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}