initial commit

master
Avril 4 years ago
commit a36aa03c48
Signed by: flanchan
GPG Key ID: 284488987C31F630

2
.gitignore vendored

@ -0,0 +1,2 @@
*~
target/

543
Cargo.lock generated

@ -0,0 +1,543 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "bytes"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "filetime"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "affc17579b132fc2461adf7c575cc6e8b134ebca52c51f5411388965227dc695"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"winapi 0.3.9",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "fsevent"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6"
dependencies = [
"bitflags",
"fsevent-sys",
]
[[package]]
name = "fsevent-sys"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0"
dependencies = [
"libc",
]
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
dependencies = [
"bitflags",
"fuchsia-zircon-sys",
]
[[package]]
name = "fuchsia-zircon-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
[[package]]
name = "futures"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
name = "futures-core"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399"
[[package]]
name = "futures-executor"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"
[[package]]
name = "futures-macro"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39"
dependencies = [
"proc-macro-hack",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "futures-sink"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc"
[[package]]
name = "futures-task"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626"
dependencies = [
"once_cell",
]
[[package]]
name = "futures-util"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"pin-project",
"pin-utils",
"proc-macro-hack",
"proc-macro-nested",
"slab",
]
[[package]]
name = "hermit-abi"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9"
dependencies = [
"libc",
]
[[package]]
name = "inotify"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f"
dependencies = [
"bitflags",
"inotify-sys",
"libc",
]
[[package]]
name = "inotify-sys"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0"
dependencies = [
"libc",
]
[[package]]
name = "iovec"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
dependencies = [
"libc",
]
[[package]]
name = "kernel32-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
dependencies = [
"winapi 0.2.8",
"winapi-build",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
[[package]]
name = "libc"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10"
[[package]]
name = "log"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
dependencies = [
"cfg-if",
]
[[package]]
name = "lolicron"
version = "0.1.0"
dependencies = [
"futures",
"notify",
"sexp",
"tokio",
]
[[package]]
name = "memchr"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
[[package]]
name = "mio"
version = "0.6.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430"
dependencies = [
"cfg-if",
"fuchsia-zircon",
"fuchsia-zircon-sys",
"iovec",
"kernel32-sys",
"libc",
"log",
"miow",
"net2",
"slab",
"winapi 0.2.8",
]
[[package]]
name = "mio-extras"
version = "2.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19"
dependencies = [
"lazycell",
"log",
"mio",
"slab",
]
[[package]]
name = "miow"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
dependencies = [
"kernel32-sys",
"net2",
"winapi 0.2.8",
"ws2_32-sys",
]
[[package]]
name = "net2"
version = "0.2.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7"
dependencies = [
"cfg-if",
"libc",
"winapi 0.3.9",
]
[[package]]
name = "notify"
version = "4.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80ae4a7688d1fab81c5bf19c64fc8db920be8d519ce6336ed4e7efe024724dbd"
dependencies = [
"bitflags",
"filetime",
"fsevent",
"fsevent-sys",
"inotify",
"libc",
"mio",
"mio-extras",
"walkdir",
"winapi 0.3.9",
]
[[package]]
name = "num_cpus"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "once_cell"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d"
[[package]]
name = "pin-project"
version = "0.4.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca4433fff2ae79342e497d9f8ee990d174071408f28f726d6d83af93e58e48aa"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "0.4.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c0e815c3ee9a031fdf5af21c10aa17c573c9c6a566328d99e3936c34e36461f"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "pin-project-lite"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "proc-macro-hack"
version = "0.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598"
[[package]]
name = "proc-macro-nested"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a"
[[package]]
name = "proc-macro2"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "sexp"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8fa7ac9df84000b0238cf497cb2d3056bac2ff2a7d8cf179d2803b4b58571f"
[[package]]
name = "slab"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
[[package]]
name = "syn"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cdb98bcb1f9d81d07b536179c269ea15999b5d14ea958196413869445bb5250"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "tokio"
version = "0.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd"
dependencies = [
"bytes",
"fnv",
"lazy_static",
"mio",
"num_cpus",
"pin-project-lite",
"slab",
"tokio-macros",
]
[[package]]
name = "tokio-macros"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "walkdir"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
dependencies = [
"same-file",
"winapi 0.3.9",
"winapi-util",
]
[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "ws2_32-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
dependencies = [
"winapi 0.2.8",
"winapi-build",
]

@ -0,0 +1,18 @@
[package]
name = "lolicron"
version = "0.1.0"
authors = ["Avril <flanchan@cumallover.me>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
default = ["threaded"]
threaded = ["tokio/rt-threaded"]
[dependencies]
tokio = {version = "0.2", features=["time", "macros", "io-driver", "sync", "rt-core"]}
futures = "*"
notify = "4.0"
sexp = "1.1"

@ -0,0 +1,63 @@
use super::*;
use std::{
str,
fmt,
};
/// Target for oneshots
#[derive(Debug)]
pub enum Target
{
/// Fired when daemon starts
Startup,
/// Fired when config reloaded
Reload,
/// Fired only when user tells it to
Specific,
}
/// When the job should be ran
#[derive(Debug)]
pub enum When
{
/// Run when a target is reached
Oneshot(Target),
/// Run on an interval
Interval(interval::Time),
}
/// A command for `Job`
#[derive(Debug)]
pub struct Command
{
program: String,
args: Vec<String>,
}
/// Output for `define-job`
#[derive(Debug)]
pub struct Job
{
name: String,
when: Vec<When>,
what: Command,
}
#[derive(Debug)]
pub enum Error {
}
impl std::error::Error for Error{}
impl std::fmt::Display for Error
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
todo!()
}
}

@ -0,0 +1,319 @@
use std::{
str,
num::{self, NonZeroU64},
fmt,
convert::TryFrom,
iter::FromIterator,
};
/// Interval for job, in miliseconds.
#[derive(Debug,Clone,PartialEq,Eq,Hash,Ord,PartialOrd)]
pub enum Unit
{
Second,
Minute,
Hour,
Day,
Week,
Year,
// Fuck months lole
Aeon,
}
impl Unit
{
/// Multiplier to get to miliseconds
#[inline]
pub const fn multiplier(&self) -> u64 {
use Unit::*;
match self {
Second => 1000,
Minute => Second.multiplier() * 60,
Hour => Minute.multiplier() * 60,
Day => Hour.multiplier() * 24,
Week => Day.multiplier() * 7,
Year => Week.multiplier() * 52,
Aeon => Year.multiplier() * 1000000,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord,PartialOrd)]
pub struct Time
{
unit: Unit,
value: NonZeroU64,
/// Value in miliseconds
absolute: Option<NonZeroU64>,
}
impl FromIterator<Time> for Time
{
fn from_iter<I: IntoIterator<Item=Time>>(iter: I) -> Self
{
iter.into_iter().fold(Option::<Self>::None, |acc, x| {
Some(match acc {
Some(acc) => acc.extend(x).unwrap(),
None => x,
})
}).unwrap()
}
}
impl Time
{
fn into_abs(mut self) -> Result<Self, ParseError>
{
self.absolute = Some(NonZeroU64::try_from(self.unit.multiplier().checked_mul(u64::from(self.value)).ok_or(ParseError::InvalidNumber(None))?)?);
Ok(self)
}
/// Create a new `Time`
///
/// # Panics
/// If value in miliseconds would overflow a 64 bit unisnged integer
pub fn new(value: NonZeroU64, unit: Unit) -> Self
{
Self {
unit,
value,
absolute: None,
}.into_abs().expect("operation would result in overflow")
}
/// Create a new `Time` from miliseconds.
///
/// # Panics
/// If `value` is less than 1 second (1000ms)
pub fn from_ms(value: NonZeroU64) -> Self
{
let value_sec = NonZeroU64::try_from(u64::from(value) / 1000).expect("absolute `value` is too small for `Time`");
Self{
unit: Unit::Second,
value: value_sec,
absolute: Some(value),
}
}
/// Attempt to create a new `Time` from miliseconds.
pub fn try_from_ms(value: NonZeroU64) -> Result<Self, num::TryFromIntError>
{
let value_sec = NonZeroU64::try_from(u64::from(value) / 1000)?;
Ok(Self{
unit: Unit::Second,
value: value_sec,
absolute: Some(value),
})
}
}
impl Time
{
pub fn extend(self, other: Self) -> Result<Self, ParseError>
{
Ok(Self::try_from_ms(unsafe{NonZeroU64::new_unchecked(u64::from(self.absolute.unwrap()) + u64::from(other.absolute.unwrap()))})?)
}
pub fn parse_chars<I>(from: &mut I) -> Result<Self, ParseError>
where I: Iterator<Item=char>
{
let mut token = String::new();
let mut unit = None;
let mut is_num = true;
for (i, tok) in (0..).zip(from)
{
if is_num && tok.is_whitespace() {
continue;
} else if is_num && tok.is_ascii_digit() {
token.push(tok);
} else if unit.is_none() {
is_num=false;
unit = match tok {
's' | 'S' => Some(Unit::Second),
'm' | 'M' => Some(Unit::Minute),
'h' | 'H' => Some(Unit::Hour),
'd' | 'D' => Some(Unit::Day),
'w' | 'W' => Some(Unit::Week),
'y' | 'Y' => Some(Unit::Year),
'A' => Some(Unit::Aeon),
white if white.is_whitespace() => continue,
_ => return Err(ParseError::UnexpectedToken(tok, i)),
};
break;
} else {return Err(ParseError::UnexpectedToken(tok, i));}
}
Self {
unit: unit.unwrap_or(Unit::Second),
value: token.parse::<NonZeroU64>()?,
absolute: None,
}.into_abs()
}
}
impl str::FromStr for Time
{
type Err = ParseError;
fn from_str(from: &str) -> Result<Self,Self::Err>
{
Self::parse_chars(&mut from.chars())
}
}
/// Parse many `Time`s
pub fn parse_many(string: impl AsRef<str>, output: &mut Vec<Time>) -> Result<usize, ParseErrorMany>
{
let chars = string.as_ref();
let mut chars = chars.chars();
let mut i=0;
while chars.as_str().len() > 0 {
output.push(match Time::parse_chars(&mut chars) {
Ok(v) => v,
Err(e) => return Err(ParseErrorMany{error: e, line: i}),
});
i+=1;
}
Ok(i)
}
/// Parse many `Time`s into a single one
pub fn parse_many_into(string: impl AsRef<str>) -> Result<Time, ParseErrorMany>
{
let mut output = Vec::new();
parse_many(string, &mut output)?;
let mut line=0;
output.into_iter().fold(Option::<Result<Time, ParseErrorMany>>::None, |acc, x| {
line+=1;
match acc {
Some(Ok(acc)) => Some(acc.extend(x).map_err(|error| ParseErrorMany{error, line: line-1})),
None => Some(Ok(x)),
x=> x,
}
}).unwrap_or(Err(ParseErrorMany{error: ParseError::Empty, line:0}))
}
#[derive(Debug)]
pub struct ParseErrorMany {
error: ParseError,
line: usize,
}
impl std::error::Error for ParseErrorMany{}
impl std::fmt::Display for ParseErrorMany
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "atom {}: {}", self.line, self.error)
}
}
#[cfg(nightly)]
type IntErrorKind = std::num::IntErrorKind;
#[cfg(not(nightly))]
type IntErrorKind = ();
#[derive(Debug)]
pub enum ParseError {
Empty,
UnexpectedToken(char, usize),
InvalidNumber(Option<IntErrorKind>),
}
impl std::error::Error for ParseError{}
impl std::fmt::Display for ParseError
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
match self {
Self::Empty => write!(f, "empty string is not a time"),
Self::UnexpectedToken(tok, loc) => write!(f, "unexpected token `{}' at position {}", tok, loc),
Self::InvalidNumber(None) => write!(f, "number must be a valid non-zero 64 bit integer"),
#[cfg(nightly)]
Self::InvalidNumber(Some(kind)) => write!(f, "failed to parse integer: {:?}", kind),
#[cfg(not(nightly))]
Self::InvalidNumber(Some(_)) => write!(f, "failed to parse integer"),
}
}
}
impl From<num::TryFromIntError> for ParseError
{
fn from(_from: num::TryFromIntError) -> Self
{
Self::InvalidNumber(None)
}
}
impl From<num::ParseIntError> for ParseError
{
#[allow(unused_variables)]
fn from(from: num::ParseIntError) -> Self
{
#[cfg(nightly)]
return Self::InvalidNumber(Some(from.kind().clone()));
#[cfg(not(nightly))]
return Self::InvalidNumber(Some(()));
}
}
#[cfg(test)]
mod tests
{
use super::*;
#[test]
fn parse_single()
{
let time: Time = "100A".parse().expect("parse failed");
assert_eq!(time, Time::new(NonZeroU64::try_from(100).unwrap(), Unit::Aeon));
}
#[test]
fn parse_many()
{
macro_rules! time {
($value:expr, $unit:expr) => {
Time::new(NonZeroU64::try_from($value).unwrap(), $unit)
}
};
let mut output = Vec::new();
let time = super::parse_many("1w4d 3h 2m 10s", &mut output).expect("parse failed");
assert_eq!(output.len(), time);
assert_eq!(&output[..],&[time!(1, Unit::Week),
time!(4, Unit::Day),
time!(3, Unit::Hour),
time!(2, Unit::Minute),
time!(10, Unit::Second)]);
}
#[test]
fn parse_many_into_one()
{
macro_rules! time {
($value:expr, $unit:expr) => {
Time::new(NonZeroU64::try_from($value).unwrap(), $unit)
}
};
let mut output = Vec::new();
const STR_FROM: &str = "1w4d 3h 2m 10s";
let time = super::parse_many(STR_FROM, &mut output).expect("parse failed");
assert_eq!(output.len(), time);
assert_eq!(&output[..],&[time!(1, Unit::Week),
time!(4, Unit::Day),
time!(3, Unit::Hour),
time!(2, Unit::Minute),
time!(10, Unit::Second)]);
let output: Time = output.iter().cloned().collect();
let input = super::parse_many_into(STR_FROM).expect("parse into failed");
assert_eq!(output,input);
}
}

@ -0,0 +1,50 @@
#![cfg_attr(nightly, int_error_matching)]
#![allow(dead_code)]
use tokio::{
select,
time::{
self,
Duration,
},
sync::{
oneshot,
},
task,
};
mod interval;
mod config;
async fn do_thing_every() -> Result<(oneshot::Sender<()>, task::JoinHandle<()>), Box<dyn std::error::Error>>
{
let mut interval = time::interval(Duration::from_secs(1));
let (tx, mut rx) = oneshot::channel();
let handle = tokio::spawn(async move {
println!("starting?");
loop {
select!{
_ = interval.tick() => {
// Do the things
println!("yes");
}
_ = &mut rx => {
// We got cancel
println!("no");
break;
}
}
}
});
Ok((tx, handle))
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
Loading…
Cancel
Save