redirectionio 3.1.0

Redirection IO Library to handle matching rule, redirect and filtering headers and body.
Documentation
use std::{cmp::Ordering, fmt::Display};

use chrono::{DateTime, Datelike, Utc, Weekday};
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, Hash, Serialize, Deserialize, Eq, PartialEq)]
pub struct Weekdays(pub Vec<Weekday>);
#[derive(Clone, Debug, Hash, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd)]
pub struct RouteWeekday {
    pub weekdays: Weekdays,
}

impl Ord for Weekdays {
    fn cmp(&self, other: &Self) -> Ordering {
        let self_num = self.0.iter().map(|weekday| weekday.num_days_from_monday());
        let other_num = other.0.iter().map(|weekday| weekday.num_days_from_monday());

        self_num.cmp(other_num)
    }
}

impl PartialOrd for Weekdays {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl RouteWeekday {
    pub fn from_weekdays(weekdays: &Vec<String>) -> Option<RouteWeekday> {
        let mut route_weekdays = Vec::new();

        for weekday in weekdays {
            match weekday.parse::<Weekday>() {
                Ok(wd) => route_weekdays.push(wd),
                Err(err) => {
                    tracing::error!("cannot parse weekday {weekday}: {err}");
                }
            }
        }

        if route_weekdays.is_empty() {
            return None;
        }

        Some(RouteWeekday {
            weekdays: Weekdays(route_weekdays),
        })
    }

    pub fn match_datetime(&self, datetime: &DateTime<Utc>) -> bool {
        self.weekdays.0.contains(&datetime.weekday())
    }
}

impl Display for RouteWeekday {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "in({:?})", self.weekdays)
    }
}