Time lib and http

This commit is contained in:
allexanderbergmns
2026-08-25 15:39:44 +02:00
parent 4ccc8a0f95
commit 5daadce7a9
11 changed files with 310 additions and 7 deletions
+34
View File
@@ -0,0 +1,34 @@
// http.vr — the HTTP client (needs network access).
// vr run examples/http.vr
//
// http.get / http.post return a struct with `status` (int) and `body`
// (string). Network failures throw and can be caught with try/catch;
// HTTP-level errors (404, 500) come back as normal responses.
import http
import json
fn main() {
let res = http.get("https://httpbin.org/get")
println("status: " + str(res.status))
let data = json.decode(res.body)
println("your IP (from httpbin): " + str(data.origin))
let post = http.post("https://httpbin.org/post", "name=vuurraaf")
let echo = json.decode(post.body)
println("echoed: " + str(echo.data))
// a 404 is a response, not an exception
let nf = http.get("https://httpbin.org/status/404")
println("not found status: " + str(nf.status))
// network failures are catchable
try {
http.get("http://127.0.0.1:1/nope")
println("unreachable")
} catch e {
println("caught connection error")
}
println("done")
}
+75 -1
View File
@@ -5,6 +5,15 @@ import os
import json
import strings
import math
import http
import time
enum Suit {
hearts
diamonds
clubs
spades
}
fn add(a, b) {
return a + b
@@ -310,7 +319,7 @@ fn test_module_imports() {
}
assert os.base("a/b/c.vr") == "c.vr"
assert os.dir("a/b/c.vr") == "a/b"
assert len(os.glob("lib/*.vr")) == 4
assert len(os.glob("lib/*.vr")) == 6
let tmp = os.join(os.cwd(), "tmp_test.txt")
os.write_lines(tmp, ["x", "y"])
assert len(os.read_lines(tmp)) == 2
@@ -381,6 +390,71 @@ fn test_closures() {
assert tag("warn") == "[warn]"
}
fn test_enums() {
// variant values
assert Suit.hearts == 0
assert Suit.spades == 3
// enum.count()
assert Suit.hearts.count() == 4
// enum.to_string()
assert Suit.spades.to_string() == "spades"
// enums in expressions
let next = Suit.hearts + 1
assert next == 1
// enum iteration
let names = []
for s in Suit {
names = push(names, s.to_string())
}
assert len(names) == 4
assert names[0] == "hearts"
assert names[3] == "spades"
// match on enum values
assert suit_code(Suit.clubs) == "c"
assert suit_code(Suit.hearts) == "h"
}
fn suit_code(s) {
match s {
Suit.hearts { return "h" }
Suit.clubs { return "c" }
else { return "?" }
}
}
fn test_http_errors() {
// offline-safe: connecting to a closed local port fails fast
try {
http.get("http://127.0.0.1:1/nope")
assert false
} catch e {
assert len(e) > 0
}
}
fn test_time() {
let t = time.now()
assert t > 1700000000
// format produces fixed-width strings
let day = time.date(t)
assert len(day) == 10
assert day[4] == "-"[0]
let full = time.format(t, "YYYY-MM-DD HH:mm:ss")
assert len(full) == 19
// parse round-trips within a second
let back = time.parse(full)
assert abs(back - t) <= 1
// ms is more precise than seconds
assert time.ms() > t * 1000
// invalid input throws
try {
time.parse("not a date")
assert false
} catch e {
assert len(e) > 0
}
}
fn test_failing() {
// this one is meant to fail — shows up in `vr test` output
assert 1 == 2
+29
View File
@@ -0,0 +1,29 @@
// time.vr — date/time helpers.
// vr run examples/time.vr
//
// Tokens follow the Moment.js style: YYYY, MM, DD, HH, mm, ss, with
// literals like "-" and ":". All values are Unix epoch seconds.
import time
fn main() {
let now = time.now()
println("epoch seconds: " + str(now))
println("date: " + time.date(now))
println("clock: " + time.clock(now))
println("full: " + time.format(now, "YYYY-MM-DD HH:mm:ss"))
println("custom: " + time.format(now, "MM/DD/YYYY"))
// parse a timestamp back to epoch seconds
let parsed = time.parse("2026-08-25 12:00:00")
println("parsed epoch: " + str(parsed))
// milliseconds for timing
let start = time.ms()
let x = 0
for i in 0..100000 {
x = x + i
}
let elapsed = time.ms() - start
println("loop took " + str(elapsed) + "ms (checksum " + str(x) + ")")
}