use std::convert::TryFrom;
use jsonpath_lib::select as matches_json_path;
use serde_json::{from_slice as deserialize, Value};
use wiremock::{Match, Request};
use super::BodyPatternDto;
pub struct JsonPathContainsMatcher(String, String);
impl Match for JsonPathContainsMatcher {
fn matches(&self, req: &Request) -> bool {
deserialize::<Value>(&req.body).ok().as_ref()
.and_then(|it| matches_json_path(it, &self.0).ok())
.filter(|matched| !matched.is_empty())
.filter(|matched| {
matched.iter()
.all(|it| it.as_str().map(|c| c.contains(self.1.as_str())).unwrap_or_default())
})
.is_some()
}
}
impl TryFrom<&BodyPatternDto> for JsonPathContainsMatcher {
type Error = anyhow::Error;
fn try_from(body: &BodyPatternDto) -> anyhow::Result<Self> {
if body.is_by_json_path_contains() {
body.expression.as_ref()
.and_then(|path| body.contains.as_ref().map(|contains| (path, contains)))
.map(|(path, contains)| JsonPathContainsMatcher(path.to_string(), contains.to_owned()))
.ok_or_else(|| anyhow::Error::msg("No json path with contains matcher found"))
} else { anyhow::Result::Err(anyhow::Error::msg("No json path with contains matcher found")) }
}
}