local e={}e.__index=e local function Q(Q,U)return setmetatable({[e]=true,__completed=Q;__value=U},e)end function e.completed(e)return Q(true,e)end function e.canceled()return Q(false)end function e.isCancelable(Q)return type(Q)=="\116\097\098\108\101"and Q[e]end function e.unpack(e)return e.__completed,e.__value end function e.unwrapOrDie(Q)assert(e.isCancelable(Q),"\'\115\101\108\102\' \109\117\115\116 \098\101 \097 \067\097\110\099\101\108\097\098\108\101")assert(message==nil or type(message)=="\115\116\114\105\110\103","\'\109\101\115\115\097\103\101\' \109\117\115\116 \098\101 \110\105\108 \111\114 \097 \115\116\114\105\110\103")if not Q.__completed then if message~=nil then error(("\067\097\110\099\101\108\097\098\108\101\058\117\110\119\114\097\112\079\114\068\105\101\040\041 \102\097\105\108\101\100\058 \037\115"):format(message),2)else error("\067\097\110\099\101\108\097\098\108\101\058\117\110\119\114\097\112\079\114\068\105\101\040\041 \102\097\105\108\101\100",2)end end return Q.__value end function e.isCompleted(e)return e.__completed end function e.isCanceled(e)return not e.__completed end function e.map(U,Q)assert(e.isCancelable(U),"\'\115\101\108\102\' \109\117\115\116 \098\101 \097 \067\097\110\099\101\108\097\098\108\101")if U.__completed then return e.completed(Q(U.__value))else return U end end function e.andThen(U,Q)assert(e.isCancelable(U),"\'\115\101\108\102\' \109\117\115\116 \098\101 \097 \067\097\110\099\101\108\097\098\108\101")if U.__completed then local P=Q(U.__value)assert(e.isCancelable(P))return P else return U end end function e.__tostring(e)if e.__completed then return("\067\097\110\099\101\108\097\098\108\101\040\099\111\109\112\108\101\116\101\100\058 \037\115\041"):format(tostring(e.__value))else return"\067\097\110\099\101\108\097\098\108\101\040\099\097\110\099\101\108\101\100\041"end end return e
local Cancelable = {}
Cancelable.__index = Cancelable

local function createCancelable(completed, value)
	return setmetatable({
		[Cancelable] = true,
		__completed = completed,
		__value = value,
	}, Cancelable)
end

function Cancelable.completed(value)
	return createCancelable(true, value)
end

function Cancelable.canceled()
	return createCancelable(false)
end

function Cancelable.isCancelable(value)
	return type(value) == "table" and value[Cancelable]
end

function Cancelable:unpack()
	return self.__completed, self.__value
end

function Cancelable:unwrapOrDie()
	assert(Cancelable.isCancelable(self), "'self' must be a Cancelable")
	assert(message == nil or type(message) == "string", "'message' must be nil or a string")

	if not self.__completed then
		if message ~= nil then
			error(("Cancelable:unwrapOrDie() failed: %s"):format(message), 2)
		else
			error("Cancelable:unwrapOrDie() failed", 2)
		end
	end

	return self.__value
end

function Cancelable:isCompleted()
	return self.__completed
end

function Cancelable:isCanceled()
	return not self.__completed
end

function Cancelable:map(functor)
	assert(Cancelable.isCancelable(self), "'self' must be a Cancelable")

	if self.__completed then
		return Cancelable.completed((functor(self.__value)))
	else
		return self
	end
end

function Cancelable:andThen(functor)
	assert(Cancelable.isCancelable(self), "'self' must be a Cancelable")

	if self.__completed then
		local cancelable = functor(self.__value)
		assert(Cancelable.isCancelable(cancelable))

		return cancelable
	else
		return self
	end
end

function Cancelable:__tostring()
	if self.__completed then
		return ("Cancelable(completed: %s)"):format(tostring(self.__value))
	else
		return "Cancelable(canceled)"
	end
end

return Cancelable