/
EnumUtils.lua
134 lines (111 loc) · 3.03 KB
/
EnumUtils.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
--[=[
Helds encode Roblox enums into a string
@class EnumUtils
]=]
local EnumUtils = {}
--[=[
Encodes the value as a string. Note the general format will be such that the string is indexed
using a regular Lua value. For example:
```lua
print(EnumUtils.encodeAsString(Enum.KeyCode.E)) --> Enum.KeyCode.E
```
@param enumItem EnumItem
@return EnumItem
]=]
function EnumUtils.encodeAsString(enumItem)
assert(typeof(enumItem) == "EnumItem", "Bad enumItem")
return ("Enum.%s.%s"):format(tostring(enumItem.EnumType), enumItem.Name)
end
--[=[
Returns whether an enum is of the expected type. Useful for asserts.
```lua
assert(EnumUtils.isOfType(Enum.KeyCode, enumItem))
```
@param expectedEnumType EnumType
@param enumItem any
@return boolean -- True if is of type
@return string -- Error message if there is an error.
]=]
function EnumUtils.isOfType(expectedEnumType, enumItem)
assert(typeof(expectedEnumType) == "Enum", "Bad enum")
if typeof(enumItem) ~= "EnumItem" then
return false, ("Bad enumItem. Expected enumItem to be %s, got %s '%s'"):format(tostring(expectedEnumType), typeof(enumItem), tostring(enumItem))
end
if enumItem.EnumType == expectedEnumType then
return true
else
return false, ("Bad enumItem. Expected enumItem to be %s, got %s"):format(tostring(expectedEnumType), EnumUtils.encodeAsString(enumItem))
end
end
--[=[
Attempts to cast an item into an enum
@param enumType EnumType
@param value any
@return EnumItem
]=]
function EnumUtils.toEnum(enumType, value)
assert(typeof(enumType) == "Enum", "Bad enum")
if typeof(value) == "EnumItem" then
if value.EnumType == enumType then
return value
else
return nil
end
elseif type(value) == "number" then
-- There has to be a better way, right?
for _, item in pairs(enumType:GetEnumItems()) do
if item.Value == value then
return item
end
end
return nil
elseif type(value) == "string" then
local result = nil
pcall(function()
result = enumType[value]
end)
if result then
return result
end
-- Check full string name qualifier
local decoded = EnumUtils.decodeFromString(value)
if decoded and decoded.EnumType == enumType then
return decoded
else
return nil
end
end
end
--[=[
Returns true if the value is an encoded enum
@param value any? -- String to decode
@return boolean
]=]
function EnumUtils.isEncodedEnum(value)
return EnumUtils.decodeFromString(value) ~= nil
end
--[=[
Decodes the enum from the string name encoding
@param value string? -- String to decode
@return EnumItem
]=]
function EnumUtils.decodeFromString(value)
if type(value) ~= "string" then
return nil
end
local enumType, enumName = string.match(value, "^Enum%.([^%.%s]+)%.([^%.%s]+)$")
if enumType and enumName then
local enumValue
local ok, err = pcall(function()
enumValue = Enum[enumType][enumName]
end)
if not ok then
warn(err, ("[EnumUtils.decodeFromString] - Failed to decode %q into an enum value due to %q"):format(value, tostring(err)))
return nil
end
return enumValue
else
return nil
end
end
return EnumUtils