Module:Game Rating

local cargo = require('Module:Cargo') local fp = require('Module:Std/functional') local std = require('Module:Std') local table = require('Module:Std/table') local getArgs = require('Module:Arguments').getArgs

local data = require('Module:GameRating/Data') local table_RatingOrganizations= 'RatingOrganizations' local table_Ratings= 'Ratings' local table_GameRatings= 'GameRatings'

local p = {}

--- -- Template:GameRating noinclude ---

-- As of 2017 it is not possible to declare multiple Cargo tables per page. -- Having multiple subpages call this function is a workaround to that. -- (The tables are effectively declared on the subpages, but the declaration code is all in one place.) function p.declareTables return fp.case(mw.title.getCurrentTitle.subpageText, {       [table_RatingOrganizations]= function            return cargo.declare(table_RatingOrganizations, { shortName= 'String', fullName= 'String', region= 'String', })       end,        [table_Ratings]= function(s)             return cargo.declare(table_Ratings, { organization= 'String', code= 'String', full= 'String', })       end,        [table_GameRatings]= function        return cargo.declare(table_GameRatings, { organization= 'String', rating= 'String', release= 'String', })       end,    }) end

function p.attachTables local attachMessages = fp.map(cargo.declare, {table_RatingOrganizations, table_Ratings, table_GameRatings}) return fp.reduce(function(acc, msg)       return acc .. '\n\n' .. msg    end, '', attachMessages) end

function p.storeOrganizationData for organizationName, organizationData in pairs(data.organizations) do       cargo.store(table_RatingOrganizations, {            shortName= organizationName,            fullName= organizationData.fullName,            region= organizationData.region,        }) for _,rating in pairs(organizationData.ratings) do           cargo.store(table_Ratings, {                organization= organizationName,                code= rating.code or rating,                full= rating.full or '',            }) end end end

--- -- Template:GameRating includeonly ---

local function find(predicate, tbl) return fp.filter(predicate, tbl)[1] end

local function validate(organizationName, ratingCode) local organization = data.organizations[organizationName] if not organization then local organizations = fp.compose(table.keys, table.sort)(data.organizations) error(           string.format("\"%s\" is not among the known rating organizations, which are: %s." .. " If %s is in fact a valid rating organization, please add it to Module:GameRating/Data.", organizationName, std.tostring(organizations), organizationName )       )    end local ratings = fp.map(function(rating) return rating.code or rating end, organization.ratings) if not table.contains(ratings, ratingCode) then error(           string.format( "\"%s\" is not among the known ratings for %s, which are: %s." .. " If %s is in fact a valid rating, please add it to Module:GameRating/Data.", ratingCode, organizationName, std.tostring(ratings), ratingCode )       )    end end

function p.main(frame) return p._main(getArgs(frame, { wrappers= {'Template:GameRating', 'Template:GameRating/sandbox'} })) end

function p._main(args) local organizationName, ratingCode, release = args[1], args[2], args.release validate(organizationName, ratingCode) cargo.store(table_GameRatings, {       organization= organizationName,        rating= ratingCode,        release= release or '',    }) local organization = data.organizations[organizationName] local result = string.format("%s: %s",        mw.getCurrentFrame:expandTemplate{            title= 'Exp',            args= {                string.format('%s (%s)', organization.fullName, organization.region),                organizationName,            }        },        ratingCode    ) if release then local releaseText = tostring(   		mw.html.create('span')    			:css('font-size', 'smaller')    			:wikitext(string.format("(%s)", release))		) result = result .. ' ' .. releaseText end return result end

return p