Started writing cron expression parser [CI SKIP]

cron
Jef Roosens 2022-04-10 16:17:50 +02:00
parent e890128bda
commit 6d60ea1538
Signed by untrusted user: Jef Roosens
GPG Key ID: B75D4F293C7052DB
5 changed files with 91 additions and 1 deletions

View File

@ -60,6 +60,10 @@ fmt:
vet:
$(V) vet -W $(SRC_DIR)
.PHONY: test
test:
$(V) test $(SRC_DIR)
# Build & patch the V compiler
.PHONY: v
v: v/v

View File

@ -1,7 +1,32 @@
module cron
import git
import datatypes
import time
struct ScheduledBuild {
repo git.GitRepo
timestamp time.Time
}
fn (r1 ScheduledBuild) < (r2 ScheduledBuild) bool {
return r1.timestamp < r2.timestamp
}
pub fn cron(conf Config) ? {
repos_map := git.get_repos(conf.address, conf.api_key) ?
// mut queue := datatypes.MinHeap<ScheduledBuild>{}
// repos_map := git.get_repos(conf.address, conf.api_key) ?
// for _, repo in repos_map {
// scheduled := ScheduledBuild{
// repo: repo
// timestamp: 25
// }
// queue.insert(scheduled)
// }
// println(queue)
exp := "10/2 5 *"
println(parse_expression(exp) ?)
}

View File

@ -0,0 +1,55 @@
module cron
import math
struct CronExpression {
minutes []u32
hours []u32
days []u32
}
// parse_range parses a given string into a range of integers, if possible.
fn parse_range(s string, min u32, max u32) ?[]u32 {
mut out := []u32{}
mut start := min
mut interval := u32(1)
if s != '*' {
exps := s.split('/')
if exps.len > 1 {
interval = exps[1].u32()
}
// Here, s solely consists of a number, so that's the only value we
// should return.
else{
return [exps[0].u32()]
}
if exps[0] != '*' {
start = math.max(exps[0].u32(), min)
}
}
for start <= max {
out << start
start += interval
}
return out
}
// min hour day month day-of-week
fn parse_expression(exp string) ?CronExpression {
parts := exp.split(' ')
if parts.len != 3 {
return error("Expression must contain 5 space-separated parts.")
}
return CronExpression{
minutes: parse_range(parts[0], 0, 59) ?
hours: parse_range(parts[1], 0, 23) ?
days: parse_range(parts[2], 0, 31) ?
}
}

View File

@ -0,0 +1,5 @@
module cron
fn test_parse_star_range() {
assert parse_range('*', 0, 5) == [0, 1, 2, 3, 4, 5]
}

View File

@ -44,6 +44,7 @@ pub fn reader_to_file(mut reader io.BufferedReader, length int, path string) ? {
for to_write > 0 {
// TODO don't just loop infinitely here
bytes_written := file.write(buf[bytes_read - to_write..bytes_read]) or { continue }
// file.flush()
to_write = to_write - bytes_written
}