ok got Tasks has due func
parent
c5ed06b76c
commit
50e9c80473
|
|
@ -10,6 +10,68 @@ fn main() {
|
|||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct Tasks(Vec<Task>);
|
||||
|
||||
impl Tasks {
|
||||
pub fn new() -> Tasks {
|
||||
Tasks(vec![])
|
||||
}
|
||||
|
||||
pub fn from_reader(r: impl std::io::Read) -> Result<Tasks, String> {
|
||||
let mut result = Tasks::new();
|
||||
match serde_yaml::from_reader::<_, Vec<serde_yaml::Value>>(r) {
|
||||
Ok(v) => {
|
||||
result.0.extend(v.iter().map(|x| {
|
||||
Task::from_value(x.clone())
|
||||
}));
|
||||
Ok(result)
|
||||
},
|
||||
Err(msg) => Err(format!("failed to read: {}", msg)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
pub fn due(&self) -> Tasks {
|
||||
Tasks(self.0.iter()
|
||||
.filter(|x| x.is_due())
|
||||
.map(|x| x.clone())
|
||||
.collect()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_tasks {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn due() {
|
||||
let tasks = Tasks::from_reader(
|
||||
std::fs::File::open("./src/testdata/tasks_due_scheduled_done.yaml").expect("failed to open file")
|
||||
).expect("failed to read file");
|
||||
eprintln!("{:?}", tasks);
|
||||
assert_eq!(2, tasks.due().len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_reader() {
|
||||
let tasks = Tasks::from_reader(
|
||||
std::fs::File::open("./src/testdata/mvp.yaml").expect("failed to open file")
|
||||
).expect("failed to read file");
|
||||
assert_eq!(2, tasks.0.len());
|
||||
assert_eq!(1, tasks.0[0].0.len());
|
||||
assert!(tasks.0[0].get("is".to_string()).is_some());
|
||||
assert_eq!("x".to_string(), tasks.0[0].get("is".to_string()).unwrap());
|
||||
assert_eq!(1, tasks.0[1].0.len());
|
||||
assert_eq!("y and z".to_string(), tasks.0[1].get("is".to_string()).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone)]
|
||||
pub struct Task(serde_yaml::Mapping);
|
||||
|
||||
impl Task {
|
||||
|
|
@ -17,7 +79,7 @@ impl Task {
|
|||
Task(serde_yaml::Mapping::new())
|
||||
}
|
||||
|
||||
pub fn from_reader_value(r: impl std::io::Read) -> Result<Task, String> {
|
||||
pub fn from_reader(r: impl std::io::Read) -> Result<Task, String> {
|
||||
match serde_yaml::from_reader::<_, serde_yaml::Value>(r) {
|
||||
Ok(v) => Ok(Task::from_value(v)),
|
||||
Err(msg) => Err(format!("failed to read value: {}", msg)),
|
||||
|
|
@ -33,21 +95,12 @@ impl Task {
|
|||
result
|
||||
}
|
||||
|
||||
pub fn from_reader(r: impl std::io::Read) -> Result<Vec<Task>, String> {
|
||||
let mut result = vec![];
|
||||
match serde_yaml::from_reader::<_, Vec<serde_yaml::Value>>(r) {
|
||||
Ok(v) => {
|
||||
result.extend(v.iter().map(|x| {
|
||||
Task::from_value(x.clone())
|
||||
}));
|
||||
Ok(result)
|
||||
},
|
||||
Err(msg) => Err(format!("failed to read: {}", msg)),
|
||||
}
|
||||
pub fn is_done(&self) -> bool {
|
||||
self.0.len() == 1 && self.get_value("done".to_string()).is_some()
|
||||
}
|
||||
|
||||
pub fn is_due(&self) -> bool {
|
||||
self.is_due_at(TS::now())
|
||||
self.is_due_at(TS::now()) && !self.is_done()
|
||||
}
|
||||
|
||||
fn is_due_at(&self, now: TS) -> bool {
|
||||
|
|
@ -87,7 +140,7 @@ impl Task {
|
|||
None => None,
|
||||
Some(v) => match v.as_str() {
|
||||
Some(s) => Some(s.to_string()),
|
||||
None => {assert!(false, "got not a string"); None },
|
||||
None => None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -117,25 +170,15 @@ mod test_task {
|
|||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn from_reader_testdata() {
|
||||
let tasks = Task::from_reader(
|
||||
std::fs::File::open("./src/testdata/mvp.yaml").expect("failed to open file")
|
||||
).expect("failed to read file");
|
||||
assert_eq!(2, tasks.len());
|
||||
assert_eq!(1, tasks[0].0.len());
|
||||
assert!(tasks[0].get("is".to_string()).is_some());
|
||||
assert_eq!("x".to_string(), tasks[0].get("is".to_string()).unwrap());
|
||||
assert_eq!(1, tasks[1].0.len());
|
||||
assert_eq!("y and z".to_string(), tasks[1].get("is".to_string()).unwrap());
|
||||
|
||||
let task = Task::from_reader_value(
|
||||
fn from_reader() {
|
||||
let task = Task::from_reader(
|
||||
std::fs::File::open("./src/testdata/mvp.uuid-123-456-xyz.yaml").expect("failed to open file")
|
||||
).expect("failed to read 123...");
|
||||
assert_eq!(1, task.0.len());
|
||||
assert!(task.get("is".to_string()).is_some());
|
||||
assert_eq!("plaintext".to_string(), task.get("is".to_string()).unwrap());
|
||||
|
||||
let task = Task::from_reader_value(
|
||||
let task = Task::from_reader(
|
||||
std::fs::File::open("./src/testdata/mvp.uuid-789-012-abc.yaml").expect("failed to open file")
|
||||
).expect("failed to read 789...");
|
||||
assert_eq!(3, task.0.len());
|
||||
|
|
@ -146,6 +189,18 @@ mod test_task {
|
|||
assert!(task.is_due());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_done() {
|
||||
let mut t = Task::new();
|
||||
t.set("done".to_string(), "anything".to_string());
|
||||
eprintln!("{:?}", t.0);
|
||||
assert!(t.is_done());
|
||||
|
||||
t.set_value("done".to_string(), serde_yaml::Value::Null);
|
||||
eprintln!("{:?}", t.0);
|
||||
assert!(t.is_done());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn crud() {
|
||||
let mut t = Task::new();
|
||||
|
|
@ -442,6 +497,13 @@ impl TS {
|
|||
Ok(v) => { return Ok(TS(v.and_utc().timestamp() as u64)) },
|
||||
_ => {},
|
||||
};
|
||||
match NaiveDateTime::parse_from_str(
|
||||
&format!("{}T00:00", src),
|
||||
"%Y-%m-%dT%H:%M",
|
||||
) {
|
||||
Ok(v) => { return Ok(TS(v.and_utc().timestamp() as u64)) },
|
||||
_ => {},
|
||||
};
|
||||
Err(format!("cannot parse date format from {}", src))
|
||||
}
|
||||
|
||||
|
|
@ -477,5 +539,12 @@ mod test_ts {
|
|||
},
|
||||
Err(err) => assert!(false, "failed to parse ts: {}", err),
|
||||
};
|
||||
match TS::new("2024-05-01".to_string()) {
|
||||
Ok(ts) => {
|
||||
assert_eq!(1714521600, ts.unix());
|
||||
assert_eq!("2024-05-01T00:00Z", ts.to_string());
|
||||
},
|
||||
Err(err) => assert!(false, "failed to parse ts: {}", err),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
- 1do: due
|
||||
schedule: 2006-04-05
|
||||
- 2do: scheduled
|
||||
schedule: 2099-04-05
|
||||
- 3do: repeating scheduled
|
||||
schedule: 0 0 1 1 *
|
||||
ts: 2001-02-03T04:05:06Z
|
||||
- done:
|
||||
do: done
|
||||
schedule: 2006-04-05
|
||||
Loading…
Reference in New Issue