This commit is contained in:
lx
2026-07-06 14:01:11 -04:00
commit c4f97d729d
16468 changed files with 935321 additions and 0 deletions
@@ -0,0 +1,100 @@
local function strict(t, name)
name = name or tostring(t)
return setmetatable(t, {
__index = function(self, key)
local message = ("%q (%s) is not a valid member of %s"):format(
tostring(key),
typeof(key),
name
)
error(message, 2)
end,
__newindex = function(self, key, value)
local message = ("%q (%s) is not a valid member of %s"):format(
tostring(key),
typeof(key),
name
)
error(message, 2)
end,
})
end
local function addEnumValue(enumInternal, enumInternalRawValues, enumName, valueName, rawValue)
local isValueNameString = typeof(valueName) == "string"
assert(isValueNameString, "Only string names are supported for enums!")
if isValueNameString then
assert(valueName ~= "fromRawValue", "fromRawValue is reserved")
assert(valueName ~= "isEnumValue", "isEnumValue is reserved")
end
assert(enumInternal[valueName] == nil, "Enum value names can only be used once!")
assert(enumInternalRawValues[valueName] == nil, "Enum values can only be used once!")
local value = newproxy(true)
local valueMetatable = getmetatable(value)
valueMetatable.__tostring = function()
return ("%s.%s"):format(enumName, valueName)
end
valueMetatable.__index = strict({
rawValue = function()
return rawValue
end
})
enumInternal[valueName] = value
enumInternalRawValues[rawValue] = value
end
local function enumerate(enumName, values)
assert(typeof(enumName) == "string", "Bad argument #1 - enums must be created using a string name!")
assert(typeof(values) == "table", "Bad argument #2 - enums must be created using a table!")
local enumInternal = {}
local enumInternalRawValues = {}
-- Allow a list-like syntax for string enums for convenience
if values[1] ~= nil then
for _, valueName in ipairs(values) do
addEnumValue(enumInternal, enumInternalRawValues, enumName, valueName, valueName)
end
else
for valueName, rawValue in pairs(values) do
addEnumValue(enumInternal, enumInternalRawValues, enumName, valueName, rawValue)
end
end
function enumInternal.fromRawValue(rawValue)
return enumInternalRawValues[rawValue]
end
function enumInternal.isEnumValue(value)
if typeof(value) ~= "userdata" then
return false
end
for _, enumValue in pairs(enumInternal) do
if enumValue == value then
return true
end
end
return nil
end
local enum = newproxy(true)
local meta = getmetatable(enum)
meta.__index = strict(enumInternal, enumName)
meta.__tostring = function()
return enumName
end
return enum
end
return enumerate
@@ -0,0 +1,69 @@
return function()
local enumerate = require(script.Parent.enumerate)
describe("Any Enum", function()
local AnyEnum = enumerate("AnyEnum", { "A", "B", "C" })
it("should be valid", function()
expect(AnyEnum).to.be.ok()
end)
it("should have the correct name", function()
expect(tostring(AnyEnum)).to.be.equal("AnyEnum")
end)
it("cannot be altered", function()
expect(function()
AnyEnum.A = "B"
end).to.throw()
end)
it("should error when accessing an invalid value", function()
expect(function()
local _ = AnyEnum.D
end).to.throw()
end)
it("should have values that can be compared for equality", function()
expect(AnyEnum.A).to.equal(AnyEnum.A)
expect(AnyEnum.A == AnyEnum.B).to.equal(false)
end)
it("should have userdata values", function()
expect(typeof(AnyEnum.A)).to.equal("userdata")
end)
it("should have values with correct rawValue types", function()
expect(typeof(AnyEnum.A.rawValue())).to.equal("string")
end)
it("should have values with a useful name", function()
expect(tostring(AnyEnum.A)).to.equal("AnyEnum.A")
end)
it("should have values with correct rawValues", function()
expect(AnyEnum.A.rawValue()).to.equal("A")
end)
it("should return the correct value from a rawValue", function()
expect(AnyEnum.fromRawValue("A")).to.equal(AnyEnum.A)
end)
it("should detect whether a value is an enum value", function()
expect(AnyEnum.isEnumValue(AnyEnum.A)).to.equal(true)
expect(AnyEnum.isEnumValue("A")).to.equal(false)
end)
end)
it("should error when creating an enum with a non-string name", function()
expect(function()
enumerate(1, { "A", "B", "C" })
end).to.throw()
end)
it("should error when creating an enum with duplicate values", function()
expect(function()
enumerate(1, { "A", "B", "C", "C" })
end).to.throw()
end)
end
@@ -0,0 +1 @@
return require(script.enumerate)
@@ -0,0 +1,7 @@
return function()
local enumerate = require(script.Parent)
it("should load a function", function()
expect(typeof(enumerate)).to.equal("function")
end)
end
@@ -0,0 +1,5 @@
# Generated by Rotriever. Format subject to change in future releases.
name = "roblox/enumerate"
version = "1.0.0"
commit = "48daaf0df47eaf36c154d691a8320239e4a1312e"
source = "url+https://github.com/roblox/enumerate"