➕ offset feature
parent
0a73740b16
commit
bb619b2452
|
@ -7,6 +7,9 @@ type Result <T> = std::result::Result <T, crate::error::Error>;
|
|||
pub struct Config {
|
||||
pub interval_secs: u64,
|
||||
pub prompt: String,
|
||||
|
||||
// Open dev tools in a web browser and run `Math.random () * 2225`
|
||||
pub offset_secs: u64,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
|
@ -14,6 +17,7 @@ impl Default for Config {
|
|||
Self {
|
||||
interval_secs: 2225,
|
||||
prompt: "Write a journal entry, then hit Tab, Enter to submit it.".into (),
|
||||
offset_secs: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +39,11 @@ impl Config {
|
|||
let val = u64::from_str (&val).map_err (|_| CannotParseArg ("--interval-secs <u64>"))?;
|
||||
that.interval_secs = val;
|
||||
}
|
||||
else if arg == "--offset-secs" {
|
||||
let val = args.next ().ok_or (ParamNeedsArg ("--offset-secs"))?;
|
||||
let val = u64::from_str (&val).map_err (|_| CannotParseArg ("--offset-secs <u64>"))?;
|
||||
that.offset_secs = val;
|
||||
}
|
||||
else if arg == "--prompt" {
|
||||
let val = args.next ().ok_or (ParamNeedsArg ("--prompt"))?;
|
||||
that.prompt = val;
|
||||
|
@ -44,3 +53,11 @@ impl Config {
|
|||
Ok (that)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg (test)]
|
||||
mod test {
|
||||
#[test]
|
||||
fn parse () {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -21,12 +21,13 @@ use tokio::{
|
|||
io::AsyncWriteExt,
|
||||
time::{
|
||||
Duration,
|
||||
interval,
|
||||
interval_at,
|
||||
},
|
||||
};
|
||||
|
||||
mod config;
|
||||
mod error;
|
||||
mod offset;
|
||||
|
||||
use config::Config;
|
||||
use error::Error;
|
||||
|
@ -40,7 +41,13 @@ async fn main () -> Result <(), Error> {
|
|||
let app = app::App::default ();
|
||||
|
||||
tokio::spawn (async move {
|
||||
let mut i = interval (Duration::from_secs (config.interval_secs));
|
||||
let mut i = interval_at (
|
||||
offset::get_next_tick (
|
||||
config.interval_secs,
|
||||
config.offset_secs,
|
||||
).into (),
|
||||
Duration::from_secs (config.interval_secs),
|
||||
);
|
||||
i.set_missed_tick_behavior (tokio::time::MissedTickBehavior::Skip);
|
||||
|
||||
loop {
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
use std::{
|
||||
time::{
|
||||
Duration,
|
||||
Instant,
|
||||
SystemTime,
|
||||
}
|
||||
};
|
||||
|
||||
pub fn get_next_tick (interval_secs: u64, offset_secs: u64) -> Instant {
|
||||
let now_sys = SystemTime::now ();
|
||||
let now_mono = Instant::now ();
|
||||
|
||||
let phase = get_phase (now_sys, interval_secs, offset_secs);
|
||||
now_mono.checked_add (Duration::from_millis (interval_secs * 1000 - u64::try_from (phase).unwrap ())).unwrap ()
|
||||
}
|
||||
|
||||
fn get_phase (now: SystemTime, interval_secs: u64, offset_secs: u64) -> u64 {
|
||||
let ms_since_epoch = now.duration_since (SystemTime::UNIX_EPOCH).unwrap ().as_millis ();
|
||||
u64::try_from ((ms_since_epoch + u128::from (offset_secs) * 1000) % (u128::from (interval_secs) * 1000)).unwrap ()
|
||||
}
|
||||
|
||||
#[cfg (test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test () {
|
||||
let now = SystemTime::UNIX_EPOCH.checked_add (Duration::from_secs (1649201544)).unwrap ();
|
||||
|
||||
assert_eq! (get_phase (now, 2225, 0), 394000);
|
||||
assert_eq! (get_phase (now, 2225, 30), 424000);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue