mirror of
https://git.pumpin.online/funkpower/typikon.git
synced 2026-10-23 03:07:12 +00:00
a C ABI, so this can be embedded rather than spawned
Every desktop shell that reads typikon today runs the binary and parses its JSON. That costs about 1.5ms and is the right answer for a calendar that changes once a day, but it is the wrong shape for anything with an FFI and no business spawning a process on every redraw. Dates cross as Julian Day Numbers, so no struct layout is part of the contract. A day is opaque and owns its strings, built once when it is reckoned: an accessor returns the same borrowed pointer every time, so a statusline polling one in a loop allocates nothing. The accessors carry every field of the JSON, so nothing on the other side needs a parser. The Python bindings and this were resolving a jurisdiction by two copies of the same logic, and the copy here leaked one per call. Both now share jurisdictions::resolve_full, which interns the combinations instead. The header is a promise made in a second file, and a second file drifts: a test reads both and fails if either has a symbol the other does not, and does the same for the LuaJIT cdef, where a stale declaration is a segfault rather than a compile error.
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
-- What a statusline would do with it: one line, no subprocess, no JSON.
|
||||
--
|
||||
-- cargo build --release --features capi
|
||||
-- TYPIKON_LIB=target/release/libtypikon.so \
|
||||
-- luajit examples/lua/statusline.lua rocor
|
||||
|
||||
package.path = (arg[0]:match("(.*/)") or "./") .. "?.lua;" .. package.path
|
||||
|
||||
local typikon = require("typikon")
|
||||
|
||||
local day, e = typikon.today({ jurisdiction = arg[1] })
|
||||
if not day then
|
||||
io.stderr:write(e, "\n")
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
-- The one line.
|
||||
print(("%s %s %s%s"):format(
|
||||
day.emoji,
|
||||
day.church_date,
|
||||
day.sign and (day.sign .. " ") or "",
|
||||
day.title))
|
||||
|
||||
-- And the detail a tooltip would carry.
|
||||
print()
|
||||
print((" %-14s %s (%s, %s)"):format("reckoning", day.jurisdiction, day.calendar, day.tradition))
|
||||
print((" %-14s %s%s"):format("fast", day.fast_label,
|
||||
day.is_obligatory and " [obligatory]" or ""))
|
||||
if day.binds then
|
||||
print((" %-14s %s"):format("law requires", day.binds))
|
||||
end
|
||||
print((" %-14s %s"):format("because", day.reason))
|
||||
if day.season then print((" %-14s %s"):format("season", day.season)) end
|
||||
if day.cycle then print((" %-14s %s"):format("cycle", day.cycle)) end
|
||||
for i = 2, #day.commemorations do
|
||||
print((" %-14s %s"):format(i == 2 and "also" or "", day.commemorations[i]))
|
||||
end
|
||||
|
||||
print((" %-14s %d days (%s)"):format("to Pascha", day.days_to_pascha,
|
||||
("%04d-%02d-%02d"):format(typikon.ymd(day.pascha_jdn))))
|
||||
Reference in New Issue
Block a user