Module:FunList/Enumerable

From Melvor Idle

Implementation of the base Enumerable class. This class and its inheritants map the Lua pairs and ipairs functions to a state machine. Inheritants must implement the getEnumerator function that returns an Module:FunList/Enumerator object.


-- Makes the class that inherits this enumerable with pairs and ipairs
--- @class Enumerable
local Enumerable = {}
local Enumerable_mt = {
	__index = Enumerable,
	__pairs = Enumerable.getPairs,
	__ipairs = Enumerable.getiPairs
}

function Enumerable.new()
	local self = setmetatable({}, Enumerable_mt)
	return self
end

--- Enumerate all elements
--- @param isArray? boolean
--- @return Enumerator
function Enumerable:getEnumerator(isArray)
	error("This method must be implemented by the derived class")
end

---comment
---@param enum Enumerable
---@param startIndex any
local function overridePairs(enum, startIndex)
	local new = enum:getEnumerator(startIndex == 0)
	local next = new.moveNext
	local function iterator(t, k)
		if next(new) == true then
			return new.index, new.current
		end
		return nil, nil
	end

	return iterator, new, new.index
end

function Enumerable:getPairs()
    return overridePairs(self, nil)
end

function Enumerable:getiPairs()
    return overridePairs(self, 0)
end

--- @param obj any
--- @return boolean
function Enumerable.isEnumerable(obj)
	-- Instead of checking type, we just really only care
	-- if obj implements the getEnumerator function.
	if obj == nil then
		return false
	end
    return (obj.getEnumerator ~= nil)
end

return Enumerable