close tho

master
Bel LaPointe 2024-05-15 22:53:34 -04:00
parent 66f533a210
commit 00813e39a9
3 changed files with 100 additions and 2 deletions

10
pttodoer/Cargo.lock generated
View File

@ -70,6 +70,15 @@ version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
[[package]]
name = "croner"
version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "516aad5374ea0ea75a0f0f4512fb4e7ad46c5eeff9971cb8ebc8fd74f1cd16c1"
dependencies = [
"chrono",
]
[[package]]
name = "equivalent"
version = "1.0.1"
@ -177,6 +186,7 @@ name = "pttodoer"
version = "0.1.0"
dependencies = [
"chrono",
"croner",
"regex",
"serde_yaml",
]

View File

@ -7,5 +7,6 @@ edition = "2021"
[dependencies]
chrono = "0.4.38"
croner = "2.0.4"
regex = "1.10.4"
serde_yaml = "0.9.34"

View File

@ -2,6 +2,7 @@ use serde_yaml;
use chrono::DateTime;
use chrono::naive::NaiveDateTime;
use regex::Regex;
use croner;
fn main() {
println!("{:?}", Task::new())
@ -65,6 +66,29 @@ impl When {
_ => None,
}
}
fn next(&self, now: TS) -> TS {
match Duration::new(self.0.clone()) {
Ok(duration) => {
return TS::from_unix(
now.unix() + duration.0
);
},
_ => {},
};
match TS::new(self.0.clone()) {
Ok(ts) => { return ts; },
_ => {},
};
match Cron::new(self.0.clone()) {
Ok(x) => {
return x.next(now);
},
_ => {},
};
assert!(false, "invalid when cooked");
now
}
}
#[cfg(test)]
@ -75,7 +99,34 @@ mod test_when {
fn parse() {
match When::new("1d2h3m".to_string()) {
Ok(when) => {
assert_eq!(1714521600 + 60*3 + 60*60*2 + 60*60*24*1, when.next(TS::new("2024-05-01T00").unwrap()));
assert_eq!(
1714521600 + 60*3 + 60*60*2 + 60*60*24*1,
when.next(
TS::new("2024-05-01T00".to_string())
.unwrap()
).unix()
);
},
Err(err) => assert!(false, "failed to parse when: {}", err),
};
match When::new("2024-05-01T00:00Z".to_string()) {
Ok(when) => {
assert_eq!(
1714521600 ,
when.next(
TS::new("2024-05-01T00".to_string())
.unwrap()
).unix()
);
},
Err(err) => assert!(false, "failed to parse when: {}", err),
};
match When::new("0 1 * * *".to_string()) {
Ok(when) => {
assert_eq!(
1714521600 + 60*60,
when.next(TS::from_unix(1714521600)).unix()
);
},
Err(err) => assert!(false, "failed to parse when: {}", err),
};
@ -87,10 +138,42 @@ struct Cron(String);
impl Cron {
fn new(src: String) -> Result<Cron, String> {
Err("not impl".to_string())
match croner::Cron::new(src.as_str()).parse() {
Ok(_) => Ok(Cron{0: src}),
Err(msg) => Err(format!("bad cron: {}", msg)),
}
}
fn next(&self, now: TS) -> TS {
match croner::Cron::new(self.0.as_str()).parse() {
Ok(c) => match c.find_next_occurrence(
&DateTime::from_timestamp(now.unix() as i64, 0).unwrap(),
true,
) {
Ok(dt) => {
return TS::from_unix(dt.timestamp() as u64);
},
Err(_) => TS::from_unix(0),
},
_ => TS::from_unix(0),
}
}
}
#[cfg(test)]
mod test_cron {
use super::*;
#[test]
fn parse() {
match Cron::new("1 * * * *".to_string()) {
Ok(c) => assert_eq!(1714525200+60, c.next(TS::from_unix(1714525200)).unix()),
Err(err) => assert!(false, "failed to parse cron: {}", err),
};
}
}
#[derive(Debug)]
struct Duration(u64);
@ -157,6 +240,10 @@ mod test_duration {
struct TS(u64);
impl TS {
fn from_unix(src: u64) -> TS {
TS{0: src}
}
fn new(src: String) -> Result<TS, String> {
match DateTime::parse_from_str(
&format!("{} +0000", src),