Skip to content

Commit

Permalink
Merge pull request #5 from 4t145/master
Browse files Browse the repository at this point in the history
release 0.1.3
  • Loading branch information
4t145 authored Jun 25, 2024
2 parents 1b4e8fc + ae0477a commit 55f1bf5
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "tsuki-scheduler"
version = "0.1.2"
version = "0.1.3"
edition = "2021"
authors = ["4t145<[email protected]>"]
description = "A simple, light wight, composable and extensible scheduler for every runtime."
Expand Down
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,34 @@ let schedule = Once::new(start_time)
.before(start_time + TimeDelta::days(100));
```

For some case you want to use a certain type for all schedule, you can use `Box<dyn Schedule>`, and there's a builder api for it.
```rust
use tsuki_scheduler::prelude::*;
use chrono::{Utc, TimeDelta};
let cron_list = Vec::<Cron<Utc>>::new();
// add some cron expr

// ...

// build schedule
let start_time = now() + TimeDelta::seconds(10);
let mut schedule_builder = Once::new(start_time).dyn_builder()
.then(
Cron::utc_from_cron_expr("00 10 * * * *")
.expect("invalid cron")
.or(Period::new(
TimeDelta::minutes(80),
start_time + TimeDelta::minutes(80),
))
.throttling(TimeDelta::minutes(30)),
)
.before(start_time + TimeDelta::days(100));
// collect all cron expr
schedule_builder = cron_list.into_iter().fold(schedule_builder, ScheduleDynBuilder::or);
let schedule = schedule_builder.build();

```

### Add executes and delete tasks
```rust
use tsuki_scheduler::prelude::*;
Expand Down
6 changes: 5 additions & 1 deletion src/schedule/cron.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ impl Cron<Local> {
}
}

impl<Z: chrono::offset::TimeZone> Schedule for Cron<Z> {
impl<Z> Schedule for Cron<Z>
where
Z: chrono::offset::TimeZone + Send + 'static,
Z::Offset: Send + 'static,
{
fn peek_next(&mut self) -> Option<Dtu> {
self.iterator.peek().map(DateTime::to_utc)
}
Expand Down
2 changes: 1 addition & 1 deletion src/schedule/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl<I: Iterator<Item = Dtu>> Iter<I> {
}
impl<I> Schedule for Iter<I>
where
I: Iterator<Item = Dtu>,
I: Iterator<Item = Dtu> + Send + 'static,
{
fn peek_next(&mut self) -> Option<crate::Dtu> {
self.inner.peek().copied()
Expand Down
70 changes: 61 additions & 9 deletions src/schedule/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ mod period;
pub use period::*;
mod throttling;
pub use throttling::*;
mod never;
pub use never::*;

pub trait Schedule {
pub trait Schedule: Send + 'static {
fn peek_next(&mut self) -> Option<Dtu>;
fn next(&mut self) -> Option<Dtu>;
fn forward_to(&mut self, dtu: Dtu);
Expand All @@ -28,6 +30,7 @@ pub trait Schedule {
impl<T> Schedule for T
where
T: AsMut<dyn Schedule>,
T: Send + 'static,
{
fn peek_next(&mut self) -> Option<Dtu> {
self.as_mut().peek_next()
Expand Down Expand Up @@ -66,27 +69,76 @@ impl<S: Schedule> IntoSchedule for S {

/// shortcuts for creating combined schedules
pub trait ScheduleExt: Schedule + Sized {
fn or<S: Schedule>(self, other: S) -> Or<Self, S> {
or::Or::new(self, other)
fn dyn_builder(self) -> ScheduleDynBuilder {
ScheduleDynBuilder::new(self)
}
fn or<S: IntoSchedule>(self, other: S) -> Or<Self, S::Output> {
or::Or::new(self, other.into_schedule())
}
fn after(self, time: crate::Dtu) -> After<Self> {
after::After::new(time, self)
}
fn before(self, time: crate::Dtu) -> Before<Self> {
before::Before::new(time, self)
}
fn then<S: Schedule>(self, then: S) -> Then<Self, S> {
then::Then::new(self, then)
fn then<S: IntoSchedule>(self, then: S) -> Then<Self, S::Output> {
then::Then::new(self, then.into_schedule())
}
fn throttling(self, interval: chrono::TimeDelta) -> Throttling<Self> {
Throttling::new(self, interval)
}
fn dyn_box(self) -> Box<dyn Schedule>
where
Self: 'static,
{
fn dyn_box(self) -> Box<dyn Schedule> {
Box::new(self)
}
}

impl<S> ScheduleExt for S where S: Schedule + Sized {}

/// Dynamic builder api for creating combined schedules
pub struct ScheduleDynBuilder {
schedule: Box<dyn Schedule>,
}

impl Default for ScheduleDynBuilder {
fn default() -> Self {
Self {
schedule: Never.dyn_box(),
}
}
}

impl ScheduleDynBuilder {
pub fn map<S: Schedule>(self, map: impl FnOnce(Box<dyn Schedule>) -> S) -> Self {
ScheduleDynBuilder::new(map(self.schedule))
}
pub fn new<S: IntoSchedule>(schedule: S) -> Self {
Self {
schedule: schedule.into_schedule().dyn_box(),
}
}
pub fn or<S: IntoSchedule>(self, other: S) -> ScheduleDynBuilder {
self.map(|this| this.or(other))
}
pub fn after(self, time: crate::Dtu) -> ScheduleDynBuilder {
self.map(|this| this.after(time))
}
pub fn before(self, time: crate::Dtu) -> ScheduleDynBuilder {
self.map(|this| this.before(time))
}
pub fn then<S: IntoSchedule>(self, then: S) -> ScheduleDynBuilder {
self.map(|this| this.then(then))
}
pub fn throttling(self, interval: chrono::TimeDelta) -> ScheduleDynBuilder {
self.map(|this| this.throttling(interval))
}
pub fn build(self) -> Box<dyn Schedule> {
self.schedule
}
}

impl IntoSchedule for ScheduleDynBuilder {
type Output = Box<dyn Schedule>;
fn into_schedule(self) -> Self::Output {
self.build()
}
}
19 changes: 19 additions & 0 deletions src/schedule/never.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use super::Schedule;
use crate::Dtu;

/// A schedule that never runs. You may use it as a unit element for [`or`](`super::ScheduleExt::or`) combinator,
/// or to init a [`builder`](super::ScheduleDynBuilder).
#[derive(Debug, Clone, Copy, Default)]
pub struct Never;

impl Schedule for Never {
fn peek_next(&mut self) -> Option<Dtu> {
None
}

fn next(&mut self) -> Option<Dtu> {
None
}

fn forward_to(&mut self, _dtu: Dtu) {}
}

0 comments on commit 55f1bf5

Please sign in to comment.