-
-
Notifications
You must be signed in to change notification settings - Fork 83
Expand file tree
/
Copy pathrunner.lua
More file actions
63 lines (50 loc) · 1.33 KB
/
runner.lua
File metadata and controls
63 lines (50 loc) · 1.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
local wrap = require('async.wrap')
local co = coroutine
---Runs the given function
---@param func fun(): any
---@return { run: function, catch: fun(error_handler: fun(error: any)) }
local function runner(func)
local m = {
error_handler = nil,
}
local async_thunk_factory = wrap(function(handler, parent_handler_callback)
assert(type(handler) == 'function', 'type error :: expected func')
local thread = co.create(handler)
local step = nil
step = function(...)
local ok, thunk = co.resume(thread, ...)
-- when an error() is thrown after co-routine is resumed, obviously further
-- processing stops, and resume returns ok(false) and thunk(error) returns
-- the error message
if not ok then
if m.error_handler then
m.error_handler(thunk)
return
end
if parent_handler_callback then
parent_handler_callback(thunk)
return
end
error('unhandled error ' .. thunk)
end
assert(ok, thunk)
if co.status(thread) == 'dead' then
if parent_handler_callback then
parent_handler_callback(thunk)
end
else
assert(type(thunk) == 'function', 'type error :: expected func')
thunk(step)
end
end
step()
return m
end)
m.run = async_thunk_factory(func)
m.catch = function(error_handler)
m.error_handler = error_handler
return m
end
return m
end
return runner