Module:Database

From Cassette Beasts
Revision as of 21:15, 21 May 2022 by Tomc (talk | contribs)

Documentation for this module may be created at Module:Database/doc

local p = {}

local db = mw.loadData("Module:Database/data")

-- Private helpers

function table.empty(t)
	for _,_ in pairs(t) do
		return false
	end
	return true
end

function get_species(id)
	if tonumber(id) ~= nil then
		id = tonumber(id)
	end
	if type(id) == "number" then
		return db.species.by_index[id] or db.species.unknown
	else
		return db.species.by_name[id] or db.species.unknown
	end
end

function subscript(value, path, path_start)
	while value ~= nil and path[path_start] ~= nil do
		local key = path[path_start]
		if tonumber(key) ~= nil then
			value = value[tonumber(key)]
		else
			value = value[key]
		end
		path_start = path_start + 1
	end
	return value
end

function textify(frame, value)
	if value == true and frame.args.if_true ~= null then
		return frame.args.if_true
	elseif value == false and frame.args.if_false ~= nil then
		return frame.args.if_false
	elseif type(value) == "string" and frame.args["if_" .. value] ~= nil then
		return frame.args["if_" .. value]
	elseif type(value) == "table" and frame.args.if_empty ~= nil and table.empty(value) then
		return frame.args.if_empty
	elseif type(value) == "table" and frame.args["foreach"] ~= nil then
		local delim = frame.args.delim or ""
		if delim == "," then delim = delim .. " " end
		local result = ""
		local i = 1
		for key,elem in pairs(value) do
			if i > 1 then
				result = result .. delim
			end
			local args = { elem }
			if frame.args.key_param ~= nil then
				args[frame.args.key_param] = key
			end
			result = result .. frame:expandTemplate{title = frame.args["foreach"], args = args}
			i = i + 1
		end
		return result
	elseif type(value) == "table" and frame.args.delim then
		local delim = frame.args.delim
		if delim == "," then delim = delim .. " " end
		local result = ""
		for i,elem in ipairs(value) do
			if i > 1 then
				result = result .. delim
			end
			result = result .. textify(frame, elem)
		end
		return result
	end
	if type(frame.args.format) == "string" then
		value = string.format(frame.args.format, value)
	end
	if type(value) == "table" and value.name ~= nil then
		value = value.name
	end

	if value == nil then
		return ""
	elseif type(value) == "string" or type(value) == "number" or type(value) == "boolean" then
		return tostring(value)
	end
	return "<" .. tostring(value) .. ">"
end

-- Public functions for use with #invoke

function p.get_species(frame)
	local species = get_species(frame.args[1])
	return textify(frame, subscript(species, frame.args, 2))
end

function p.get_prev_species(frame)
	local species = get_species(frame.args[1])
	if species.bestiary_index ~= nil then
		species = get_species(species.bestiary_index - 1)
	end
	return textify(frame, subscript(species, frame.args, 2))
end

function p.get_next_species(frame)
	local species = get_species(frame.args[1])
	if species.bestiary_index ~= nil then
		species = get_species(species.bestiary_index + 1)
	end
	return textify(frame, subscript(species, frame.args, 2))
end

function p.species_has_family(frame)
	local species = get_species(frame.args[1])
	return not table.empty(species.evolves_from) or not table.empty(species.evolves_to)
end

return p