chore: make the fields of Planning struct public

This commit is contained in:
PoiScript 2019-04-11 23:53:43 +08:00
parent c2c554a3d5
commit 9c82b268d6
5 changed files with 231 additions and 190 deletions

View file

@ -1,4 +1,4 @@
use crate::objects::timestamp::{self, Datetime, Delay, Repeater, Timestamp};
use crate::objects::timestamp::{Datetime, Delay, Repeater, Timestamp};
use memchr::memchr;
#[cfg_attr(test, derive(PartialEq))]
@ -32,7 +32,7 @@ impl<'a> Clock<'a> {
return None;
}
match timestamp::parse_inactive(tail).map(|(t, off)| (t, tail[off..].trim_start())) {
match Timestamp::parse_inactive(tail).map(|(t, off)| (t, tail[off..].trim_start())) {
Some((
Timestamp::InactiveRange {
start,

View file

@ -1,37 +1,36 @@
use crate::objects::timestamp::{self, Timestamp};
use crate::objects::timestamp::Timestamp;
use memchr::memchr;
#[cfg_attr(test, derive(PartialEq))]
#[derive(Debug)]
pub struct Planning<'a> {
deadline: Option<Timestamp<'a>>,
scheduled: Option<Timestamp<'a>>,
closed: Option<Timestamp<'a>>,
pub deadline: Option<Timestamp<'a>>,
pub scheduled: Option<Timestamp<'a>>,
pub closed: Option<Timestamp<'a>>,
}
impl<'a> Planning<'a> {
pub(crate) fn parse(text: &'a str) -> Option<(Planning<'a>, usize)> {
let (text, off) = memchr(b'\n', text.as_bytes())
let (mut deadline, mut scheduled, mut closed) = (None, None, None);
let (mut tail, off) = memchr(b'\n', text.as_bytes())
.map(|i| (text[..i].trim(), i + 1))
.unwrap_or_else(|| (text.trim(), text.len()));
let mut words = text.split_ascii_whitespace();
let (mut deadline, mut scheduled, mut closed) = (None, None, None);
while let Some(word) = words.next() {
let next = words.next()?;
while let Some(i) = memchr(b' ', tail.as_bytes()) {
let next = &tail[i + 1..].trim_start();
macro_rules! set_timestamp {
($timestamp:expr) => {
if $timestamp.is_none() {
$timestamp = if next.starts_with('<') {
Some(
timestamp::parse_active(next)
.or_else(|| timestamp::parse_diary(next))?
.0,
)
} else if next.starts_with('[') {
Some(timestamp::parse_inactive(next)?.0)
if next.starts_with('<') {
let (timestamp, off) = Timestamp::parse_active(next)
.or_else(|| Timestamp::parse_diary(next))?;
$timestamp = Some(timestamp);
tail = &next[off..].trim_start();
} else if next.starts_with('<') {
let (timestamp, off) = Timestamp::parse_active(next)?;
$timestamp = Some(timestamp);
tail = &next[off..].trim_start();
} else {
return None;
}
@ -41,11 +40,11 @@ impl<'a> Planning<'a> {
};
}
match word {
match &tail[..i] {
"DEADLINE:" => set_timestamp!(deadline),
"SCHEDULED:" => set_timestamp!(scheduled),
"CLOSED:" => set_timestamp!(closed),
_ => (),
_ => return None,
}
}
@ -63,3 +62,31 @@ impl<'a> Planning<'a> {
}
}
}
#[cfg(test)]
mod tests {
#[test]
fn prase() {
use super::Planning;
use crate::objects::timestamp::{Datetime, Timestamp};
assert_eq!(
Planning::parse("SCHEDULED: <2019-04-08 Mon>\n"),
Some((
Planning {
scheduled: Some(Timestamp::Active {
start: Datetime {
date: (2019, 4, 8),
time: None
},
repeater: None,
delay: None
}),
closed: None,
deadline: None,
},
"SCHEDULED: <2019-04-08 Mon>\n".len()
))
)
}
}