--[[
    Returns a promise for a function which may yield. wrapAsync calls the
    the function in a coroutine and resolves with the output of the function
    after any asynchronous actions, and rejects if the function throws an error.
]]

function AsyncUtils.wrapAsync(fn)
	assert(type(fn) == "function")
	return Promise.new(
		function(resolve, reject)
			coroutine.wrap(
				function()
					local ok, result = pcall(fn)
					if ok then
						resolve(result)
					else
						reject(result)
					end
				end
			)()
		end
	)
end
