ok got Tasks has due func

master
Bel LaPointe 2024-05-22 14:30:05 -04:00
parent c5ed06b76c
commit 50e9c80473
2 changed files with 106 additions and 27 deletions

View File

@ -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),
};
}
}

View File

@ -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