Gemenon.jl/src/live.jl

68 lines
1.7 KiB
Julia

## Adapted from https://github.com/JuliaWeb/Mux.jl
import Base.Meta.isexpr
# Live-reloading utilities for maximum server uptime
mutable struct App
warez
end
mux(f) = f
mux(m, f) = x -> m(f, x)
mux(ms...) = foldr(mux, ms)
stack(m) = m
stack(m, n) = (f, x) -> m(mux(n, f), x)
stack(ms...) = foldl(stack, ms)
branch(p, t) = (f, x) -> (p(x) ? t : f)(x)
branch(p, t...) = branch(p, mux(t...))
function matchpath(target, path)
# @show target, path
params = Dict()
for i = 1:length(target)
# @show target[i], path[i]
if startswith(target[i], ":") && !isempty(path[i])
params[Symbol(target[i][2:end])] = path[i]
else
target[i] == path[i] || return
end
end
return params
end
function matchpath!(target, req)
ps = matchpath(target, req.req.path)
ps == nothing && return false
# merge!(params!(req), ps)
merge!(req.data, ps)
# splice!(req[:path], 1:length(target))
return true
end
page(p::Vector, app...) = branch(req -> length(p) == length(something(req.req.path, [])) && matchpath!(p, req),
app...)
# page(p::AbstractString, app...) = page(splitpath(p), app...)
page(app...) = page([], app...)
page(app::Function, p) = page(p, app)
macro app(def)
@assert isexpr(def, :(=))
name, warez = def.args
warez = isexpr(warez, :tuple) ?
Expr(:call, :mux, map(esc, warez.args)...) :
esc(warez)
quote
if $(Expr(:isdefined, esc(name)))
$(esc(name)).warez = $warez
else
$(esc(name)) = App($warez)
end
nothing
end
end
function serve(h::App, context, host = ip"127.0.0.1", port = 1965; kws...)
@async listen((req) -> h.warez(req), context, host, port; kws...)
end