mirror of
https://git.meli.delivery/meli/meli
synced 2024-11-17 03:26:20 +00:00
melib/datetime: add mbox date format parse
This commit is contained in:
parent
a42a6ca868
commit
29042aba59
@ -50,6 +50,7 @@ pub const RFC822_FMT_WITH_TIME: &str = "%a, %e %h %Y %H:%M:%S \0";
|
||||
pub const RFC822_FMT: &str = "%e %h %Y %H:%M:%S \0";
|
||||
pub const DEFAULT_FMT: &str = "%a, %d %b %Y %R\0";
|
||||
//"Tue May 21 13:46:22 1991\n"
|
||||
//"Wed Sep 9 00:27:54 2020\n"
|
||||
pub const ASCTIME_FMT: &str = "%a %b %d %H:%M:%S %Y\n\0";
|
||||
|
||||
extern "C" {
|
||||
@ -301,7 +302,7 @@ where
|
||||
{
|
||||
let s = CString::new(s)?;
|
||||
let mut new_tm: libc::tm = unsafe { std::mem::zeroed() };
|
||||
for fmt in &[RFC822_FMT_WITH_TIME, RFC822_FMT] {
|
||||
for fmt in &[RFC822_FMT_WITH_TIME, RFC822_FMT, ASCTIME_FMT] {
|
||||
let fmt = unsafe { CStr::from_bytes_with_nul_unchecked(fmt.as_bytes()) };
|
||||
let ret = {
|
||||
let _with_locale = Locale::new(
|
||||
|
@ -443,6 +443,65 @@ pub mod dates {
|
||||
}
|
||||
}
|
||||
|
||||
///e.g Wed Sep 9 00:27:54 2020
|
||||
///day-of-week month day time year
|
||||
///date-time = [ day-of-week "," ] date time [CFWS]
|
||||
///date = day month year
|
||||
///time = time-of-day zone
|
||||
///time-of-day = hour ":" minute [ ":" second ]
|
||||
///hour = 2DIGIT / obs-hour
|
||||
///minute = 2DIGIT / obs-minute
|
||||
///second = 2DIGIT / obs-second
|
||||
pub fn mbox_date_time(input: &[u8]) -> IResult<&[u8], UnixTimestamp> {
|
||||
let orig_input = input;
|
||||
let mut accum: SmallVec<[u8; 32]> = SmallVec::new();
|
||||
let (input, _) = opt(cfws)(input)?;
|
||||
let (input, day_of_week) = day_of_week(input)?;
|
||||
let (input, _) = opt(cfws)(input)?;
|
||||
let (input, month) = month(input)?;
|
||||
let (input, _) = opt(cfws)(input)?;
|
||||
let (input, day) = day(input)?;
|
||||
let (input, _) = opt(cfws)(input)?;
|
||||
let (input, hour) = take_n_digits(2)(input)?;
|
||||
let (input, _) = tag(":")(input)?;
|
||||
let (input, minute) = take_n_digits(2)(input)?;
|
||||
let (input, second) = opt(preceded(tag(":"), take_n_digits(2)))(input)?;
|
||||
let (input, _) = fws(input)?;
|
||||
let (input, zone) = opt(zone)(input)?;
|
||||
let (input, _) = opt(cfws)(input)?;
|
||||
let (input, year) = year(input)?;
|
||||
accum.extend_from_slice(&day_of_week);
|
||||
accum.extend_from_slice(b", ");
|
||||
accum.extend_from_slice(&day);
|
||||
accum.extend_from_slice(b" ");
|
||||
accum.extend_from_slice(&month);
|
||||
accum.extend_from_slice(b" ");
|
||||
accum.extend_from_slice(&year);
|
||||
accum.extend_from_slice(b" ");
|
||||
accum.extend_from_slice(&hour);
|
||||
accum.extend_from_slice(b":");
|
||||
accum.extend_from_slice(&minute);
|
||||
if let Some(second) = second {
|
||||
accum.extend_from_slice(b":");
|
||||
accum.extend_from_slice(&second);
|
||||
}
|
||||
if let Some((sign, zone)) = zone {
|
||||
accum.extend_from_slice(b" ");
|
||||
accum.extend_from_slice(&sign);
|
||||
accum.extend_from_slice(&zone);
|
||||
}
|
||||
match crate::datetime::rfc822_to_timestamp(accum.to_vec()) {
|
||||
Ok(t) => Ok((input, t)),
|
||||
Err(_err) => Err(nom::Err::Error(
|
||||
(
|
||||
orig_input,
|
||||
"mbox_date_time(): could not convert date from rfc822",
|
||||
)
|
||||
.into(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
///`day-of-week = ([FWS] day-name) / obs-day-of-week`
|
||||
///day-name = "Mon" / "Tue" / "Wed" / "Thu" /
|
||||
/// "Fri" / "Sat" / "Sun"
|
||||
@ -490,9 +549,9 @@ pub mod dates {
|
||||
|
||||
///year = (FWS 4*DIGIT FWS) / obs-year
|
||||
fn year(input: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||
let (input, _) = fws(input)?;
|
||||
let (input, _) = opt(fws)(input)?;
|
||||
let (input, ret) = take_n_digits(4)(input)?;
|
||||
let (input, _) = fws(input)?;
|
||||
let (input, _) = opt(fws)(input)?;
|
||||
Ok((input, ret))
|
||||
}
|
||||
|
||||
@ -511,6 +570,17 @@ pub mod dates {
|
||||
};
|
||||
Ok((rest, ret))
|
||||
})
|
||||
.or_else(|_| {
|
||||
let (rest, ret) = match mbox_date_time(&input) {
|
||||
Ok(v) => v,
|
||||
Err(_) => {
|
||||
return Err(nom::Err::Error(
|
||||
(input, "rfc5322_date(): invalid input").into(),
|
||||
));
|
||||
}
|
||||
};
|
||||
Ok((rest, ret))
|
||||
})
|
||||
.map(|(_, r)| r)
|
||||
.map_err(|err: nom::Err<ParsingError<_>>| err.into())
|
||||
/*
|
||||
@ -532,6 +602,8 @@ pub mod dates {
|
||||
assert_eq!(rfc5322_date(_s).unwrap(), rfc5322_date(__s).unwrap());
|
||||
let val = b"Fri, 23 Dec 0001 21:20:36 -0800 (PST)";
|
||||
assert_eq!(rfc5322_date(val).unwrap(), 0);
|
||||
let val = b"Wed Sep 9 00:27:54 2020";
|
||||
assert_eq!(rfc5322_date(val).unwrap(), 1599611274);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user