use crate::common::errorparse::SipParseError;
use crate::headers::{
header::{HeaderValue, HeaderValueType},
traits::SipHeaderParser,
};
use nom::{
bytes::complete::{tag, take},
character::complete::{char, digit1},
sequence::tuple,
};
pub struct Date;
impl Date {
fn is_wkday(value_name: &[u8]) -> bool {
match value_name {
b"Mon" => return true,
b"Tue" => true,
b"Wed" => true,
b"Thu" => true,
b"Fri" => true,
b"Sat" => true,
b"Sun" => true,
_ => return false,
}
}
fn is_month(value_name: &[u8]) -> bool {
match value_name {
b"Jan" => return true,
b"Feb" => true,
b"Mar" => true,
b"Apr" => true,
b"May" => true,
b"Jun" => true,
b"Jul" => true,
b"Aug" => true,
b"Sep" => true,
b"Oct" => true,
b"Nov" => true,
b"Dec" => true,
_ => return false,
}
}
}
impl SipHeaderParser for Date {
fn take_value(source_input: &[u8]) -> nom::IResult<&[u8], HeaderValue, SipParseError> {
let (input, wday) = take(3usize)(source_input)?;
if !Date::is_wkday(wday) {
return sip_parse_error!(1, "Invalid wday value in Date header");
}
let (input, _) = tag(", ")(input)?;
let (input, day) = digit1(input)?;
if day.len() > 2 {
return sip_parse_error!(1, "Invalid day value in Date header");
}
let (input, _) = char(' ')(input)?;
let (input, month) = take(3usize)(input)?;
if !Date::is_month(month) {
return sip_parse_error!(2, "Invalid month value in Date header");
}
let (input, _) = char(' ')(input)?;
let (input, year) = digit1(input)?;
if year.len() != 4 {
return sip_parse_error!(3, "Invalid year value in Date header");
}
let (input, _) = char(' ')(input)?;
let (input, (_hours, _, _mins, _, _seconds)) =
tuple((digit1, char(':'), digit1, char(':'), digit1))(input)?;
let (input, _) = char(' ')(input)?;
let (input, _) = tag("GMT")(input)?;
let (_, hdr_val) = HeaderValue::new(
&source_input[..source_input.len() - input.len()],
HeaderValueType::DateString,
None,
None,
)?;
Ok((input, hdr_val))
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_date_value() {
let (input, val) =
Date::take_value("Sat, 13 Nov 2010 23:29:00 GMT \r\n".as_bytes()).unwrap();
assert_eq!(val.vstr, "Sat, 13 Nov 2010 23:29:00 GMT");
assert_eq!(input, b" \r\n");
}
}