use std::marker::PhantomData;
use pact_models::matchingrules::{MatchingRule, MatchingRuleCategory, RuleLogic};
use pact_models::path_exp::DocPath;
use pact_models::time_utils::parse_pattern;
use crate::patterns::{JsonPattern, Pattern, StringPattern};
#[derive(Debug)]
pub struct DateTime<Nested: Pattern> {
example: String,
format: String,
phantom: PhantomData<Nested>
}
impl <Nested: Pattern> DateTime<Nested> {
pub fn new<S: Into<String>>(format: S, example: S) -> Self {
DateTime {
example: example.into(),
format: format.into(),
phantom: PhantomData
}
}
}
impl <Nested> Pattern for DateTime<Nested>
where
Nested: Pattern,
Nested::Matches: From<String> {
type Matches = Nested::Matches;
fn to_example(&self) -> Self::Matches {
From::from(self.example.clone())
}
fn to_example_bytes(&self) -> Vec<u8> {
self.example.as_bytes().to_vec()
}
fn extract_matching_rules(&self, path: DocPath, rules_out: &mut MatchingRuleCategory) {
rules_out.add_rule(path, MatchingRule::Timestamp(self.format.clone()), RuleLogic::And);
}
}
#[test]
fn datetime_is_pattern() {
use serde_json::*;
use expectest::prelude::*;
let matchable = DateTime::<JsonPattern>::new("EEE, d MMM yyyy HH:mm:ss Z", "Wed, 4 Jul 2001 12:08:56 -0700");
expect!(matchable.to_example()).to(be_equal_to("Wed, 4 Jul 2001 12:08:56 -0700"));
let mut rules = MatchingRuleCategory::empty("body");
matchable.extract_matching_rules(DocPath::root(), &mut rules);
let expected_rules = json!({
"$": {
"combine": "AND", "matchers": [
{ "match": "datetime", "format": "EEE, d MMM yyyy HH:mm:ss Z" }
]
}
});
expect!(rules.to_v3_json()).to(be_equal_to(expected_rules));
}
impl_from_for_pattern!(DateTime<JsonPattern>, JsonPattern);
impl_from_for_pattern!(DateTime<StringPattern>, StringPattern);
#[test]
fn datetime_into() {
let _: JsonPattern = DateTime::new("yyy-MM-dd", "2000-01-01").into();
let _: StringPattern = DateTime::new("yyy-MM-dd", "2000-01-01").into();
}
#[doc(hidden)]
pub fn validate_format_string<S: AsRef<str>>(format_str: S) -> String {
let format_str = format_str.as_ref();
match parse_pattern(format_str) {
Ok(_) => format_str.to_string(),
Err(msg) => panic!("could not parse datetime format string {:?}: {}", format_str, msg),
}
}
#[macro_export]
macro_rules! datetime {
($format:expr, $example:expr) => {
{
$crate::patterns::DateTime::new($crate::patterns::validate_format_string($format), $example.into())
}
}
}