I've implemented a struct
which has a list of crontab entries, each of which knows its own recurrence (such as */5 * * * *
in crontab):
extern crate chrono;
use chrono::NaiveDateTime;
pub struct Crontab<'a> {
entries: Vec<Entry<'a>>,
}
pub struct Entry<'a> {
pub recurrence: Recurrence,
pub command: &'a str,
}
pub struct Recurrence {
minutes: Vec<u8>,
hours: Vec<u8>,
days_of_month: Vec<u8>,
months: Vec<u8>,
days_of_week: Vec<u8>,
}
Based on the current time you can get the next occurrence of a command:
impl Recurrence {
pub fn next_match(&self, after: NaiveDateTime) -> NaiveDateTime {
unimplemented!()
}
}
I'm trying to write a function on Crontab
to get the Entry
which will run next (that is, for which recurrence.next_match()
is the lowest).
impl<'a> Crontab<'a> {
fn next_run(&self, from: NaiveDateTime) -> Run<'a> {
&self.entries
.into_iter()
.map(|entry| Run {
entry: &entry,
datetime: entry.recurrence.next_match(from),
})
.min_by(|this, other| this.datetime.cmp(&other.datetime))
.unwrap()
}
}
struct Run<'a> {
entry: &'a Entry<'a>,
datetime: NaiveDateTime,
}
This generates the error:
error[E0308]: mismatched types
--> src/main.rs:30:9
|
29 | fn next_run(&self, from: NaiveDateTime) -> Run<'a> {
| ------- expected `Run<'a>` because of return type
30 | / &self.entries
31 | | .into_iter()
32 | | .map(|entry| Run {
33 | | entry: &entry,
... |
36 | | .min_by(|this, other| this.datetime.cmp(&other.datetime))
37 | | .unwrap()
| |_____________________^ expected struct `Run`, found &Run<'_>
|
= note: expected type `Run<'a>`
found type `&Run<'_>`
Similar variants I've tried fail to compile with messages such as "cannot move out of borrowed content" (if changing the return type to &Run<'a>
) or that the &entry
does not live long enough.
It seems to make most sense that the Run
should have a reference to rather than a copy of the Entry
, but I'm not sure how to juggle both the lifetimes and references to get to that point (and I don't know whether 'a
refers to the same lifetime in both structs). What am I missing here?