use std::hash::{Hash, Hasher};
use crate::wiremock::MockBuilder;
use serde_json::Value;
use super::MockRegistrable;
pub mod binary_eq;
mod diff;
pub mod eq;
pub mod eq_relaxed;
pub mod json_path;
pub mod json_path_contains;
pub mod json_path_eq;
#[derive(Debug, Clone, Default, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BodyMatcherStub {
#[serde(skip_serializing_if = "Option::is_none")]
pub equal_to_json: Option<Value>,
#[serde(skip_serializing)]
pub matches_json_path: Option<String>,
#[serde(skip_serializing)]
pub expression: Option<String>,
#[serde(skip_serializing)]
pub contains: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub binary_equal_to: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ignore_extra_elements: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ignore_array_order: Option<bool>,
}
impl BodyMatcherStub {
pub fn is_exact_matching(&self) -> bool {
self.is_by_json_equality() && !self.is_ignore_extra_elements() && !self.is_ignore_array_order()
}
pub fn is_relaxed_matching(&self) -> bool {
(self.is_ignore_extra_elements() || self.is_ignore_array_order()) && self.is_by_json_equality()
}
fn is_by_json_equality(&self) -> bool {
self.equal_to_json.is_some() && self.matches_json_path.is_none() && self.expression.is_none() && self.binary_equal_to.is_none()
}
fn is_by_json_path(&self) -> bool {
self.matches_json_path.is_some() && self.equal_to_json.is_none() && self.expression.is_none()
}
fn is_by_json_path_eq(&self) -> bool {
self.expression.is_some() && self.equal_to_json.is_some()
}
fn is_by_json_path_contains(&self) -> bool {
self.expression.is_some() && self.contains.is_some()
}
fn is_by_binary_equality(&self) -> bool {
self.binary_equal_to.is_some()
}
pub fn is_ignore_extra_elements(&self) -> bool {
self.ignore_extra_elements.unwrap_or_default()
}
pub fn is_ignore_array_order(&self) -> bool {
self.ignore_array_order.unwrap_or_default()
}
}
impl MockRegistrable for Vec<BodyMatcherStub> {
fn register(&self, mut mock: MockBuilder) -> MockBuilder {
for body_pattern in self {
if let Ok(exact_json) = eq::BodyExactMatcher::try_from(body_pattern) {
mock = mock.and(exact_json)
}
if let Ok(relaxed_exact_json) = eq_relaxed::JsonBodyRelaxedMatcher::try_from(body_pattern) {
mock = mock.and(relaxed_exact_json)
}
if let Ok(json_path) = json_path::JsonPathBodyMatcher::try_from(body_pattern) {
mock = mock.and(json_path)
}
if let Ok(json_path_eq) = json_path_eq::JsonBodyPathEqMatcher::try_from(body_pattern) {
mock = mock.and(json_path_eq)
}
if let Ok(json_path_contains) = json_path_contains::JsonBodyPathContainsMatcher::try_from(body_pattern) {
mock = mock.and(json_path_contains)
}
if let Ok(binary_equal) = binary_eq::BinaryExactMatcher::try_from(body_pattern) {
mock = mock.and(binary_equal)
}
}
mock
}
}
impl PartialEq for BodyMatcherStub {
fn eq(&self, other: &Self) -> bool {
self.equal_to_json.as_ref().eq(&other.equal_to_json.as_ref())
&& self.matches_json_path.as_ref().eq(&other.matches_json_path.as_ref())
&& self.expression.as_ref().eq(&other.expression.as_ref())
&& self.contains.as_ref().eq(&other.contains.as_ref())
&& self.binary_equal_to.as_ref().eq(&other.binary_equal_to.as_ref())
&& self.ignore_extra_elements.as_ref().eq(&other.ignore_extra_elements.as_ref())
&& self.ignore_array_order.as_ref().eq(&other.ignore_array_order.as_ref())
}
}
impl Hash for BodyMatcherStub {
fn hash<H: Hasher>(&self, state: &mut H) {
if let Some(it) = self.equal_to_json.as_ref() {
it.to_string().hash(state)
};
self.matches_json_path.as_ref().hash(state);
self.expression.as_ref().hash(state);
self.contains.as_ref().hash(state);
self.binary_equal_to.as_ref().hash(state);
self.ignore_extra_elements.as_ref().hash(state);
self.ignore_array_order.as_ref().hash(state);
}
}