roblox-opencode 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +112 -122
- package/commands/setup-game.md +108 -108
- package/commands/sync-check.md +53 -53
- package/core/roblox-core.md +93 -93
- package/dist/server.js +189 -167
- package/package.json +35 -35
- package/skills/roblox-analytics/SKILL.md +277 -277
- package/skills/roblox-analytics/references/event-batcher.luau +75 -75
- package/skills/roblox-animation-vfx/SKILL.md +1325 -1325
- package/skills/roblox-architecture/SKILL.md +877 -863
- package/skills/roblox-architecture/references/combat-systems.md +1381 -1381
- package/skills/roblox-code-review/SKILL.md +686 -686
- package/skills/roblox-data/SKILL.md +889 -889
- package/skills/roblox-data/references/inventory-systems.md +1729 -1729
- package/skills/roblox-debug/SKILL.md +98 -98
- package/skills/roblox-gui/SKILL.md +1103 -1103
- package/skills/roblox-gui-fusion/SKILL.md +150 -150
- package/skills/roblox-gui-fusion/references/inventory.luau +427 -427
- package/skills/roblox-gui-fusion/references/settings-menu.luau +579 -579
- package/skills/roblox-gui-fusion/references/shop.luau +411 -411
- package/skills/roblox-luau-mastery/SKILL.md +1618 -1519
- package/skills/roblox-monetization/SKILL.md +1084 -1084
- package/skills/roblox-monetization/references/process-receipt.luau +131 -131
- package/skills/roblox-networking/SKILL.md +669 -669
- package/skills/roblox-networking/references/remote-validator.luau +193 -193
- package/skills/roblox-publish-checklist/SKILL.md +127 -127
- package/skills/roblox-runtime/SKILL.md +753 -753
- package/skills/roblox-sharp-edges/SKILL.md +294 -294
- package/skills/roblox-sync/SKILL.md +126 -126
- package/skills/roblox-testing/SKILL.md +943 -943
- package/skills/roblox-tooling/SKILL.md +149 -149
- package/vendor/LICENSES/ProfileStore-LICENSE +201 -201
- package/vendor/LICENSES/RbxUtil-LICENSE +7 -7
- package/vendor/LICENSES/promise-LICENSE +20 -20
- package/vendor/LICENSES/t-LICENSE +21 -21
- package/vendor/LICENSES/testez-LICENSE +200 -200
- package/vendor/README.md +83 -83
- package/vendor/fusion/Animation/ExternalTime.luau +83 -83
- package/vendor/fusion/Animation/Spring.luau +321 -321
- package/vendor/fusion/Animation/Stopwatch.luau +127 -127
- package/vendor/fusion/Animation/Tween.luau +187 -187
- package/vendor/fusion/Animation/getTweenDuration.luau +27 -27
- package/vendor/fusion/Animation/getTweenRatio.luau +47 -47
- package/vendor/fusion/Animation/lerpType.luau +163 -163
- package/vendor/fusion/Animation/packType.luau +99 -99
- package/vendor/fusion/Animation/springCoefficients.luau +80 -80
- package/vendor/fusion/Animation/unpackType.luau +102 -102
- package/vendor/fusion/Colour/Oklab.luau +70 -70
- package/vendor/fusion/Colour/sRGB.luau +54 -54
- package/vendor/fusion/External.luau +167 -167
- package/vendor/fusion/ExternalDebug.luau +69 -69
- package/vendor/fusion/Graph/Observer.luau +113 -113
- package/vendor/fusion/Graph/castToGraph.luau +28 -28
- package/vendor/fusion/Graph/change.luau +80 -80
- package/vendor/fusion/Graph/depend.luau +32 -32
- package/vendor/fusion/Graph/evaluate.luau +55 -55
- package/vendor/fusion/Instances/Attribute.luau +57 -57
- package/vendor/fusion/Instances/AttributeChange.luau +46 -46
- package/vendor/fusion/Instances/AttributeOut.luau +63 -63
- package/vendor/fusion/Instances/Child.luau +21 -21
- package/vendor/fusion/Instances/Children.luau +147 -147
- package/vendor/fusion/Instances/Hydrate.luau +32 -32
- package/vendor/fusion/Instances/New.luau +52 -52
- package/vendor/fusion/Instances/OnChange.luau +49 -49
- package/vendor/fusion/Instances/OnEvent.luau +53 -53
- package/vendor/fusion/Instances/Out.luau +69 -69
- package/vendor/fusion/Instances/applyInstanceProps.luau +148 -148
- package/vendor/fusion/Instances/defaultProps.luau +194 -194
- package/vendor/fusion/LICENSE +21 -21
- package/vendor/fusion/Logging/formatError.luau +48 -48
- package/vendor/fusion/Logging/messages.luau +51 -51
- package/vendor/fusion/Logging/parseError.luau +24 -24
- package/vendor/fusion/Memory/checkLifetime.luau +133 -133
- package/vendor/fusion/Memory/deriveScope.luau +23 -23
- package/vendor/fusion/Memory/deriveScopeImpl.luau +44 -44
- package/vendor/fusion/Memory/doCleanup.luau +78 -78
- package/vendor/fusion/Memory/innerScope.luau +33 -33
- package/vendor/fusion/Memory/legacyCleanup.luau +17 -17
- package/vendor/fusion/Memory/needsDestruction.luau +16 -16
- package/vendor/fusion/Memory/poisonScope.luau +33 -33
- package/vendor/fusion/Memory/scopePool.luau +54 -54
- package/vendor/fusion/Memory/scoped.luau +26 -26
- package/vendor/fusion/Memory/whichLivesLonger.luau +74 -74
- package/vendor/fusion/RobloxExternal.luau +97 -97
- package/vendor/fusion/State/Computed.luau +138 -138
- package/vendor/fusion/State/For/Disassembly.luau +210 -210
- package/vendor/fusion/State/For/ForTypes.luau +30 -30
- package/vendor/fusion/State/For/init.luau +109 -109
- package/vendor/fusion/State/ForKeys.luau +93 -93
- package/vendor/fusion/State/ForPairs.luau +96 -96
- package/vendor/fusion/State/ForValues.luau +93 -93
- package/vendor/fusion/State/Value.luau +87 -87
- package/vendor/fusion/State/castToState.luau +25 -25
- package/vendor/fusion/State/peek.luau +30 -30
- package/vendor/fusion/Types.luau +314 -314
- package/vendor/fusion/Utility/Contextual.luau +90 -90
- package/vendor/fusion/Utility/Safe.luau +22 -22
- package/vendor/fusion/Utility/isSimilar.luau +29 -29
- package/vendor/fusion/Utility/merge.luau +35 -35
- package/vendor/fusion/Utility/nameOf.luau +34 -34
- package/vendor/fusion/Utility/never.luau +13 -13
- package/vendor/fusion/Utility/nicknames.luau +10 -10
- package/vendor/fusion/Utility/xtypeof.luau +26 -26
- package/vendor/fusion/init.luau +82 -82
- package/vendor/profilestore/init.luau +2242 -2242
- package/vendor/promise/init.luau +1982 -1982
- package/vendor/rbxutil/buffer-util/Buffer.test.luau +25 -25
- package/vendor/rbxutil/buffer-util/BufferReader.luau +228 -228
- package/vendor/rbxutil/buffer-util/BufferWriter.luau +269 -269
- package/vendor/rbxutil/buffer-util/DataTypeBuffer.luau +223 -223
- package/vendor/rbxutil/buffer-util/Types.luau +60 -60
- package/vendor/rbxutil/buffer-util/index.d.ts +153 -153
- package/vendor/rbxutil/buffer-util/init.luau +41 -41
- package/vendor/rbxutil/buffer-util/package.json +16 -16
- package/vendor/rbxutil/buffer-util/wally.toml +9 -9
- package/vendor/rbxutil/comm/Client/ClientComm.luau +232 -232
- package/vendor/rbxutil/comm/Client/ClientRemoteProperty.luau +156 -156
- package/vendor/rbxutil/comm/Client/ClientRemoteSignal.luau +109 -109
- package/vendor/rbxutil/comm/Client/init.luau +135 -135
- package/vendor/rbxutil/comm/Server/RemoteProperty.luau +295 -295
- package/vendor/rbxutil/comm/Server/RemoteSignal.luau +211 -211
- package/vendor/rbxutil/comm/Server/ServerComm.luau +211 -211
- package/vendor/rbxutil/comm/Server/init.luau +140 -140
- package/vendor/rbxutil/comm/Types.luau +18 -18
- package/vendor/rbxutil/comm/Util.luau +27 -27
- package/vendor/rbxutil/comm/init.luau +35 -35
- package/vendor/rbxutil/comm/wally.toml +13 -13
- package/vendor/rbxutil/component/init.luau +759 -759
- package/vendor/rbxutil/component/init.test.luau +311 -311
- package/vendor/rbxutil/component/wally.toml +14 -14
- package/vendor/rbxutil/concur/init.luau +542 -542
- package/vendor/rbxutil/concur/init.test.luau +364 -364
- package/vendor/rbxutil/concur/wally.toml +8 -8
- package/vendor/rbxutil/enum-list/init.luau +101 -101
- package/vendor/rbxutil/enum-list/init.test.luau +91 -91
- package/vendor/rbxutil/enum-list/wally.toml +8 -8
- package/vendor/rbxutil/find/index.d.ts +20 -20
- package/vendor/rbxutil/find/init.luau +44 -44
- package/vendor/rbxutil/find/package.json +17 -17
- package/vendor/rbxutil/find/wally.toml +8 -8
- package/vendor/rbxutil/input/Gamepad.luau +559 -559
- package/vendor/rbxutil/input/Keyboard.luau +124 -124
- package/vendor/rbxutil/input/Mouse.luau +278 -278
- package/vendor/rbxutil/input/PreferredInput.luau +91 -91
- package/vendor/rbxutil/input/Touch.luau +120 -120
- package/vendor/rbxutil/input/init.luau +33 -33
- package/vendor/rbxutil/input/wally.toml +12 -12
- package/vendor/rbxutil/loader/index.d.ts +15 -15
- package/vendor/rbxutil/loader/init.luau +137 -137
- package/vendor/rbxutil/loader/wally.toml +8 -8
- package/vendor/rbxutil/log/index.d.ts +38 -38
- package/vendor/rbxutil/log/init.luau +746 -746
- package/vendor/rbxutil/log/wally.toml +8 -8
- package/vendor/rbxutil/net/init.luau +190 -190
- package/vendor/rbxutil/net/wally.toml +8 -8
- package/vendor/rbxutil/option/index.d.ts +44 -44
- package/vendor/rbxutil/option/init.luau +489 -489
- package/vendor/rbxutil/option/init.test.luau +342 -342
- package/vendor/rbxutil/option/wally.toml +8 -8
- package/vendor/rbxutil/pid/index.d.ts +53 -53
- package/vendor/rbxutil/pid/init.luau +195 -195
- package/vendor/rbxutil/pid/package.json +16 -16
- package/vendor/rbxutil/pid/wally.toml +9 -9
- package/vendor/rbxutil/quaternion/index.d.ts +117 -117
- package/vendor/rbxutil/quaternion/init.luau +570 -570
- package/vendor/rbxutil/quaternion/package.json +16 -16
- package/vendor/rbxutil/quaternion/wally.toml +9 -9
- package/vendor/rbxutil/query/index.d.ts +43 -43
- package/vendor/rbxutil/query/init.luau +117 -117
- package/vendor/rbxutil/query/package.json +18 -18
- package/vendor/rbxutil/query/wally.toml +9 -9
- package/vendor/rbxutil/sequent/index.d.ts +28 -28
- package/vendor/rbxutil/sequent/init.luau +340 -340
- package/vendor/rbxutil/sequent/package.json +16 -16
- package/vendor/rbxutil/sequent/wally.toml +9 -9
- package/vendor/rbxutil/ser/init.luau +175 -175
- package/vendor/rbxutil/ser/init.test.luau +50 -50
- package/vendor/rbxutil/ser/wally.toml +11 -11
- package/vendor/rbxutil/shake/index.d.ts +36 -36
- package/vendor/rbxutil/shake/init.luau +532 -532
- package/vendor/rbxutil/shake/init.test.luau +267 -267
- package/vendor/rbxutil/shake/package.json +16 -16
- package/vendor/rbxutil/shake/wally.toml +9 -9
- package/vendor/rbxutil/signal/index.d.ts +100 -100
- package/vendor/rbxutil/signal/init.luau +432 -432
- package/vendor/rbxutil/signal/init.test.luau +190 -190
- package/vendor/rbxutil/signal/package.json +17 -17
- package/vendor/rbxutil/signal/wally.toml +9 -9
- package/vendor/rbxutil/silo/TableWatcher.luau +65 -65
- package/vendor/rbxutil/silo/Util.luau +55 -55
- package/vendor/rbxutil/silo/init.luau +338 -338
- package/vendor/rbxutil/silo/init.test.luau +215 -215
- package/vendor/rbxutil/silo/wally.toml +8 -8
- package/vendor/rbxutil/spring/index.d.ts +40 -40
- package/vendor/rbxutil/spring/init.luau +97 -97
- package/vendor/rbxutil/spring/package.json +17 -17
- package/vendor/rbxutil/spring/wally.toml +8 -8
- package/vendor/rbxutil/stream/index.d.ts +88 -88
- package/vendor/rbxutil/stream/init.luau +597 -597
- package/vendor/rbxutil/stream/package.json +18 -18
- package/vendor/rbxutil/stream/wally.toml +9 -9
- package/vendor/rbxutil/streamable/Streamable.luau +202 -202
- package/vendor/rbxutil/streamable/StreamableUtil.luau +80 -80
- package/vendor/rbxutil/streamable/init.luau +8 -8
- package/vendor/rbxutil/streamable/wally.toml +12 -12
- package/vendor/rbxutil/symbol/init.luau +56 -56
- package/vendor/rbxutil/symbol/init.test.luau +37 -37
- package/vendor/rbxutil/symbol/wally.toml +8 -8
- package/vendor/rbxutil/table-util/init.luau +938 -938
- package/vendor/rbxutil/table-util/init.test.luau +439 -439
- package/vendor/rbxutil/task-queue/index.d.ts +27 -27
- package/vendor/rbxutil/task-queue/init.luau +97 -97
- package/vendor/rbxutil/task-queue/wally.toml +8 -8
- package/vendor/rbxutil/timer/index.d.ts +81 -81
- package/vendor/rbxutil/timer/init.luau +249 -249
- package/vendor/rbxutil/timer/init.test.luau +73 -73
- package/vendor/rbxutil/timer/wally.toml +11 -11
- package/vendor/rbxutil/tree/index.d.ts +15 -15
- package/vendor/rbxutil/tree/init.luau +137 -137
- package/vendor/rbxutil/tree/wally.toml +8 -8
- package/vendor/rbxutil/trove/index.d.ts +46 -46
- package/vendor/rbxutil/trove/init.luau +787 -787
- package/vendor/rbxutil/trove/init.test.luau +203 -203
- package/vendor/rbxutil/trove/wally.toml +8 -8
- package/vendor/rbxutil/typed-remote/init.luau +196 -196
- package/vendor/rbxutil/typed-remote/wally.toml +8 -8
- package/vendor/rbxutil/wait-for/index.d.ts +17 -17
- package/vendor/rbxutil/wait-for/init.luau +257 -257
- package/vendor/rbxutil/wait-for/init.test.luau +182 -182
- package/vendor/rbxutil/wait-for/wally.toml +11 -11
- package/vendor/t/t.lua +1350 -1350
- package/vendor/testez/Context.lua +26 -26
- package/vendor/testez/Expectation.lua +311 -311
- package/vendor/testez/ExpectationContext.lua +38 -38
- package/vendor/testez/LifecycleHooks.lua +89 -89
- package/vendor/testez/Reporters/TeamCityReporter.lua +101 -101
- package/vendor/testez/Reporters/TextReporter.lua +105 -105
- package/vendor/testez/Reporters/TextReporterQuiet.lua +96 -96
- package/vendor/testez/TestBootstrap.lua +146 -146
- package/vendor/testez/TestEnum.lua +27 -27
- package/vendor/testez/TestPlan.lua +304 -304
- package/vendor/testez/TestPlanner.lua +39 -39
- package/vendor/testez/TestResults.lua +111 -111
- package/vendor/testez/TestRunner.lua +188 -188
- package/vendor/testez/TestSession.lua +243 -243
- package/vendor/testez/init.lua +39 -39
package/vendor/t/t.lua
CHANGED
|
@@ -1,1350 +1,1350 @@
|
|
|
1
|
-
-- t: a runtime typechecker for Roblox
|
|
2
|
-
|
|
3
|
-
local t = {}
|
|
4
|
-
|
|
5
|
-
function t.type(typeName)
|
|
6
|
-
return function(value)
|
|
7
|
-
local valueType = type(value)
|
|
8
|
-
if valueType == typeName then
|
|
9
|
-
return true
|
|
10
|
-
else
|
|
11
|
-
return false, string.format("%s expected, got %s", typeName, valueType)
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
function t.typeof(typeName)
|
|
17
|
-
return function(value)
|
|
18
|
-
local valueType = typeof(value)
|
|
19
|
-
if valueType == typeName then
|
|
20
|
-
return true
|
|
21
|
-
else
|
|
22
|
-
return false, string.format("%s expected, got %s", typeName, valueType)
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
--[[**
|
|
28
|
-
matches any type except nil
|
|
29
|
-
|
|
30
|
-
@param value The value to check against
|
|
31
|
-
|
|
32
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
33
|
-
**--]]
|
|
34
|
-
function t.any(value)
|
|
35
|
-
if value ~= nil then
|
|
36
|
-
return true
|
|
37
|
-
else
|
|
38
|
-
return false, "any expected, got nil"
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
--Lua primitives
|
|
43
|
-
|
|
44
|
-
--[[**
|
|
45
|
-
ensures Lua primitive boolean type
|
|
46
|
-
|
|
47
|
-
@param value The value to check against
|
|
48
|
-
|
|
49
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
50
|
-
**--]]
|
|
51
|
-
t.boolean = t.typeof("boolean")
|
|
52
|
-
|
|
53
|
-
--[[**
|
|
54
|
-
ensures Lua primitive buffer type
|
|
55
|
-
|
|
56
|
-
@param value The value to check against
|
|
57
|
-
|
|
58
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
59
|
-
**--]]
|
|
60
|
-
t.buffer = t.typeof("buffer")
|
|
61
|
-
|
|
62
|
-
--[[**
|
|
63
|
-
ensures Lua primitive thread type
|
|
64
|
-
|
|
65
|
-
@param value The value to check against
|
|
66
|
-
|
|
67
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
68
|
-
**--]]
|
|
69
|
-
t.thread = t.typeof("thread")
|
|
70
|
-
|
|
71
|
-
--[[**
|
|
72
|
-
ensures Lua primitive callback type
|
|
73
|
-
|
|
74
|
-
@param value The value to check against
|
|
75
|
-
|
|
76
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
77
|
-
**--]]
|
|
78
|
-
t.callback = t.typeof("function")
|
|
79
|
-
t["function"] = t.callback
|
|
80
|
-
|
|
81
|
-
--[[**
|
|
82
|
-
ensures Lua primitive none type
|
|
83
|
-
|
|
84
|
-
@param value The value to check against
|
|
85
|
-
|
|
86
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
87
|
-
**--]]
|
|
88
|
-
t.none = t.typeof("nil")
|
|
89
|
-
t["nil"] = t.none
|
|
90
|
-
|
|
91
|
-
--[[**
|
|
92
|
-
ensures Lua primitive string type
|
|
93
|
-
|
|
94
|
-
@param value The value to check against
|
|
95
|
-
|
|
96
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
97
|
-
**--]]
|
|
98
|
-
t.string = t.typeof("string")
|
|
99
|
-
|
|
100
|
-
--[[**
|
|
101
|
-
ensures Lua primitive table type
|
|
102
|
-
|
|
103
|
-
@param value The value to check against
|
|
104
|
-
|
|
105
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
106
|
-
**--]]
|
|
107
|
-
t.table = t.typeof("table")
|
|
108
|
-
|
|
109
|
-
--[[**
|
|
110
|
-
ensures Lua primitive userdata type
|
|
111
|
-
|
|
112
|
-
@param value The value to check against
|
|
113
|
-
|
|
114
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
115
|
-
**--]]
|
|
116
|
-
t.userdata = t.type("userdata")
|
|
117
|
-
|
|
118
|
-
--[[**
|
|
119
|
-
ensures Lua primitive vector type
|
|
120
|
-
|
|
121
|
-
@param value The value to check against
|
|
122
|
-
|
|
123
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
124
|
-
**--]]
|
|
125
|
-
t.vector = t.type("vector")
|
|
126
|
-
|
|
127
|
-
--[[**
|
|
128
|
-
ensures value is a number and non-NaN
|
|
129
|
-
|
|
130
|
-
@param value The value to check against
|
|
131
|
-
|
|
132
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
133
|
-
**--]]
|
|
134
|
-
function t.number(value)
|
|
135
|
-
local valueType = typeof(value)
|
|
136
|
-
if valueType == "number" then
|
|
137
|
-
if value == value then
|
|
138
|
-
return true
|
|
139
|
-
else
|
|
140
|
-
return false, "unexpected NaN value"
|
|
141
|
-
end
|
|
142
|
-
else
|
|
143
|
-
return false, string.format("number expected, got %s", valueType)
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
--[[**
|
|
148
|
-
ensures value is NaN
|
|
149
|
-
|
|
150
|
-
@param value The value to check against
|
|
151
|
-
|
|
152
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
153
|
-
**--]]
|
|
154
|
-
function t.nan(value)
|
|
155
|
-
local valueType = typeof(value)
|
|
156
|
-
if valueType == "number" then
|
|
157
|
-
if value ~= value then
|
|
158
|
-
return true
|
|
159
|
-
else
|
|
160
|
-
return false, "unexpected non-NaN value"
|
|
161
|
-
end
|
|
162
|
-
else
|
|
163
|
-
return false, string.format("number expected, got %s", valueType)
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
-- roblox types
|
|
168
|
-
|
|
169
|
-
--[[**
|
|
170
|
-
ensures Roblox Axes type
|
|
171
|
-
|
|
172
|
-
@param value The value to check against
|
|
173
|
-
|
|
174
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
175
|
-
**--]]
|
|
176
|
-
t.Axes = t.typeof("Axes")
|
|
177
|
-
|
|
178
|
-
--[[**
|
|
179
|
-
ensures Roblox BrickColor type
|
|
180
|
-
|
|
181
|
-
@param value The value to check against
|
|
182
|
-
|
|
183
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
184
|
-
**--]]
|
|
185
|
-
t.BrickColor = t.typeof("BrickColor")
|
|
186
|
-
|
|
187
|
-
--[[**
|
|
188
|
-
ensures Roblox CatalogSearchParams type
|
|
189
|
-
|
|
190
|
-
@param value The value to check against
|
|
191
|
-
|
|
192
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
193
|
-
**--]]
|
|
194
|
-
t.CatalogSearchParams = t.typeof("CatalogSearchParams")
|
|
195
|
-
|
|
196
|
-
--[[**
|
|
197
|
-
ensures Roblox CFrame type
|
|
198
|
-
|
|
199
|
-
@param value The value to check against
|
|
200
|
-
|
|
201
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
202
|
-
**--]]
|
|
203
|
-
t.CFrame = t.typeof("CFrame")
|
|
204
|
-
|
|
205
|
-
--[[**
|
|
206
|
-
ensures Roblox Content type
|
|
207
|
-
|
|
208
|
-
@param value The value to check against
|
|
209
|
-
|
|
210
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
211
|
-
**--]]
|
|
212
|
-
t.Content = t.typeof("Content")
|
|
213
|
-
|
|
214
|
-
--[[**
|
|
215
|
-
ensures Roblox Color3 type
|
|
216
|
-
|
|
217
|
-
@param value The value to check against
|
|
218
|
-
|
|
219
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
220
|
-
**--]]
|
|
221
|
-
t.Color3 = t.typeof("Color3")
|
|
222
|
-
|
|
223
|
-
--[[**
|
|
224
|
-
ensures Roblox ColorSequence type
|
|
225
|
-
|
|
226
|
-
@param value The value to check against
|
|
227
|
-
|
|
228
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
229
|
-
**--]]
|
|
230
|
-
t.ColorSequence = t.typeof("ColorSequence")
|
|
231
|
-
|
|
232
|
-
--[[**
|
|
233
|
-
ensures Roblox ColorSequenceKeypoint type
|
|
234
|
-
|
|
235
|
-
@param value The value to check against
|
|
236
|
-
|
|
237
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
238
|
-
**--]]
|
|
239
|
-
t.ColorSequenceKeypoint = t.typeof("ColorSequenceKeypoint")
|
|
240
|
-
|
|
241
|
-
--[[**
|
|
242
|
-
ensures Roblox DateTime type
|
|
243
|
-
|
|
244
|
-
@param value The value to check against
|
|
245
|
-
|
|
246
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
247
|
-
**--]]
|
|
248
|
-
t.DateTime = t.typeof("DateTime")
|
|
249
|
-
|
|
250
|
-
--[[**
|
|
251
|
-
ensures Roblox DockWidgetPluginGuiInfo type
|
|
252
|
-
|
|
253
|
-
@param value The value to check against
|
|
254
|
-
|
|
255
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
256
|
-
**--]]
|
|
257
|
-
t.DockWidgetPluginGuiInfo = t.typeof("DockWidgetPluginGuiInfo")
|
|
258
|
-
|
|
259
|
-
--[[**
|
|
260
|
-
ensures Roblox Enum type
|
|
261
|
-
|
|
262
|
-
@param value The value to check against
|
|
263
|
-
|
|
264
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
265
|
-
**--]]
|
|
266
|
-
t.Enum = t.typeof("Enum")
|
|
267
|
-
|
|
268
|
-
--[[**
|
|
269
|
-
ensures Roblox EnumItem type
|
|
270
|
-
|
|
271
|
-
@param value The value to check against
|
|
272
|
-
|
|
273
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
274
|
-
**--]]
|
|
275
|
-
t.EnumItem = t.typeof("EnumItem")
|
|
276
|
-
|
|
277
|
-
--[[**
|
|
278
|
-
ensures Roblox Enums type
|
|
279
|
-
|
|
280
|
-
@param value The value to check against
|
|
281
|
-
|
|
282
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
283
|
-
**--]]
|
|
284
|
-
t.Enums = t.typeof("Enums")
|
|
285
|
-
|
|
286
|
-
--[[**
|
|
287
|
-
ensures Roblox Faces type
|
|
288
|
-
|
|
289
|
-
@param value The value to check against
|
|
290
|
-
|
|
291
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
292
|
-
**--]]
|
|
293
|
-
t.Faces = t.typeof("Faces")
|
|
294
|
-
|
|
295
|
-
--[[**
|
|
296
|
-
ensures Roblox FloatCurveKey type
|
|
297
|
-
|
|
298
|
-
@param value The value to check against
|
|
299
|
-
|
|
300
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
301
|
-
**--]]
|
|
302
|
-
t.FloatCurveKey = t.typeof("FloatCurveKey")
|
|
303
|
-
|
|
304
|
-
--[[**
|
|
305
|
-
ensures Roblox Font type
|
|
306
|
-
|
|
307
|
-
@param value The value to check against
|
|
308
|
-
|
|
309
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
310
|
-
**--]]
|
|
311
|
-
t.Font = t.typeof("Font")
|
|
312
|
-
|
|
313
|
-
--[[**
|
|
314
|
-
ensures Roblox Instance type
|
|
315
|
-
|
|
316
|
-
@param value The value to check against
|
|
317
|
-
|
|
318
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
319
|
-
**--]]
|
|
320
|
-
t.Instance = t.typeof("Instance")
|
|
321
|
-
|
|
322
|
-
--[[**
|
|
323
|
-
ensures Roblox NumberRange type
|
|
324
|
-
|
|
325
|
-
@param value The value to check against
|
|
326
|
-
|
|
327
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
328
|
-
**--]]
|
|
329
|
-
t.NumberRange = t.typeof("NumberRange")
|
|
330
|
-
|
|
331
|
-
--[[**
|
|
332
|
-
ensures Roblox NumberSequence type
|
|
333
|
-
|
|
334
|
-
@param value The value to check against
|
|
335
|
-
|
|
336
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
337
|
-
**--]]
|
|
338
|
-
t.NumberSequence = t.typeof("NumberSequence")
|
|
339
|
-
|
|
340
|
-
--[[**
|
|
341
|
-
ensures Roblox NumberSequenceKeypoint type
|
|
342
|
-
|
|
343
|
-
@param value The value to check against
|
|
344
|
-
|
|
345
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
346
|
-
**--]]
|
|
347
|
-
t.NumberSequenceKeypoint = t.typeof("NumberSequenceKeypoint")
|
|
348
|
-
|
|
349
|
-
--[[**
|
|
350
|
-
ensures Roblox OverlapParams type
|
|
351
|
-
|
|
352
|
-
@param value The value to check against
|
|
353
|
-
|
|
354
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
355
|
-
**--]]
|
|
356
|
-
t.OverlapParams = t.typeof("OverlapParams")
|
|
357
|
-
|
|
358
|
-
--[[**
|
|
359
|
-
ensures Roblox PathWaypoint type
|
|
360
|
-
|
|
361
|
-
@param value The value to check against
|
|
362
|
-
|
|
363
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
364
|
-
**--]]
|
|
365
|
-
t.PathWaypoint = t.typeof("PathWaypoint")
|
|
366
|
-
|
|
367
|
-
--[[**
|
|
368
|
-
ensures Roblox PhysicalProperties type
|
|
369
|
-
|
|
370
|
-
@param value The value to check against
|
|
371
|
-
|
|
372
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
373
|
-
**--]]
|
|
374
|
-
t.PhysicalProperties = t.typeof("PhysicalProperties")
|
|
375
|
-
|
|
376
|
-
--[[**
|
|
377
|
-
ensures Roblox Random type
|
|
378
|
-
|
|
379
|
-
@param value The value to check against
|
|
380
|
-
|
|
381
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
382
|
-
**--]]
|
|
383
|
-
t.Random = t.typeof("Random")
|
|
384
|
-
|
|
385
|
-
--[[**
|
|
386
|
-
ensures Roblox Ray type
|
|
387
|
-
|
|
388
|
-
@param value The value to check against
|
|
389
|
-
|
|
390
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
391
|
-
**--]]
|
|
392
|
-
t.Ray = t.typeof("Ray")
|
|
393
|
-
|
|
394
|
-
--[[**
|
|
395
|
-
ensures Roblox RaycastParams type
|
|
396
|
-
|
|
397
|
-
@param value The value to check against
|
|
398
|
-
|
|
399
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
400
|
-
**--]]
|
|
401
|
-
t.RaycastParams = t.typeof("RaycastParams")
|
|
402
|
-
|
|
403
|
-
--[[**
|
|
404
|
-
ensures Roblox RaycastResult type
|
|
405
|
-
|
|
406
|
-
@param value The value to check against
|
|
407
|
-
|
|
408
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
409
|
-
**--]]
|
|
410
|
-
t.RaycastResult = t.typeof("RaycastResult")
|
|
411
|
-
|
|
412
|
-
--[[**
|
|
413
|
-
ensures Roblox RBXScriptConnection type
|
|
414
|
-
|
|
415
|
-
@param value The value to check against
|
|
416
|
-
|
|
417
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
418
|
-
**--]]
|
|
419
|
-
t.RBXScriptConnection = t.typeof("RBXScriptConnection")
|
|
420
|
-
|
|
421
|
-
--[[**
|
|
422
|
-
ensures Roblox RBXScriptSignal type
|
|
423
|
-
|
|
424
|
-
@param value The value to check against
|
|
425
|
-
|
|
426
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
427
|
-
**--]]
|
|
428
|
-
t.RBXScriptSignal = t.typeof("RBXScriptSignal")
|
|
429
|
-
|
|
430
|
-
--[[**
|
|
431
|
-
ensures Roblox Rect type
|
|
432
|
-
|
|
433
|
-
@param value The value to check against
|
|
434
|
-
|
|
435
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
436
|
-
**--]]
|
|
437
|
-
t.Rect = t.typeof("Rect")
|
|
438
|
-
|
|
439
|
-
--[[**
|
|
440
|
-
ensures Roblox Region3 type
|
|
441
|
-
|
|
442
|
-
@param value The value to check against
|
|
443
|
-
|
|
444
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
445
|
-
**--]]
|
|
446
|
-
t.Region3 = t.typeof("Region3")
|
|
447
|
-
|
|
448
|
-
--[[**
|
|
449
|
-
ensures Roblox Region3int16 type
|
|
450
|
-
|
|
451
|
-
@param value The value to check against
|
|
452
|
-
|
|
453
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
454
|
-
**--]]
|
|
455
|
-
t.Region3int16 = t.typeof("Region3int16")
|
|
456
|
-
|
|
457
|
-
--[[**
|
|
458
|
-
ensures Roblox TweenInfo type
|
|
459
|
-
|
|
460
|
-
@param value The value to check against
|
|
461
|
-
|
|
462
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
463
|
-
**--]]
|
|
464
|
-
t.TweenInfo = t.typeof("TweenInfo")
|
|
465
|
-
|
|
466
|
-
--[[**
|
|
467
|
-
ensures Roblox UDim type
|
|
468
|
-
|
|
469
|
-
@param value The value to check against
|
|
470
|
-
|
|
471
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
472
|
-
**--]]
|
|
473
|
-
t.UDim = t.typeof("UDim")
|
|
474
|
-
|
|
475
|
-
--[[**
|
|
476
|
-
ensures Roblox UDim2 type
|
|
477
|
-
|
|
478
|
-
@param value The value to check against
|
|
479
|
-
|
|
480
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
481
|
-
**--]]
|
|
482
|
-
t.UDim2 = t.typeof("UDim2")
|
|
483
|
-
|
|
484
|
-
--[[**
|
|
485
|
-
ensures Roblox Vector2 type
|
|
486
|
-
|
|
487
|
-
@param value The value to check against
|
|
488
|
-
|
|
489
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
490
|
-
**--]]
|
|
491
|
-
t.Vector2 = t.typeof("Vector2")
|
|
492
|
-
|
|
493
|
-
--[[**
|
|
494
|
-
ensures Roblox Vector2int16 type
|
|
495
|
-
|
|
496
|
-
@param value The value to check against
|
|
497
|
-
|
|
498
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
499
|
-
**--]]
|
|
500
|
-
t.Vector2int16 = t.typeof("Vector2int16")
|
|
501
|
-
|
|
502
|
-
--[[**
|
|
503
|
-
ensures Roblox Vector3 type
|
|
504
|
-
|
|
505
|
-
@param value The value to check against
|
|
506
|
-
|
|
507
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
508
|
-
**--]]
|
|
509
|
-
t.Vector3 = t.typeof("Vector3")
|
|
510
|
-
|
|
511
|
-
--[[**
|
|
512
|
-
ensures Roblox Vector3int16 type
|
|
513
|
-
|
|
514
|
-
@param value The value to check against
|
|
515
|
-
|
|
516
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
517
|
-
**--]]
|
|
518
|
-
t.Vector3int16 = t.typeof("Vector3int16")
|
|
519
|
-
|
|
520
|
-
--[[**
|
|
521
|
-
ensures value is any of the given literal values
|
|
522
|
-
|
|
523
|
-
@param literals The literals to check against
|
|
524
|
-
|
|
525
|
-
@returns A function that will return true if the condition is passed
|
|
526
|
-
**--]]
|
|
527
|
-
function t.literalList(literals)
|
|
528
|
-
-- optimization for primitive types
|
|
529
|
-
local set = {}
|
|
530
|
-
for _, literal in ipairs(literals) do
|
|
531
|
-
set[literal] = true
|
|
532
|
-
end
|
|
533
|
-
return function(value)
|
|
534
|
-
if set[value] then
|
|
535
|
-
return true
|
|
536
|
-
end
|
|
537
|
-
for _, literal in ipairs(literals) do
|
|
538
|
-
if literal == value then
|
|
539
|
-
return true
|
|
540
|
-
end
|
|
541
|
-
end
|
|
542
|
-
|
|
543
|
-
return false, "bad type for literal list"
|
|
544
|
-
end
|
|
545
|
-
end
|
|
546
|
-
|
|
547
|
-
--[[**
|
|
548
|
-
ensures value is a given literal value
|
|
549
|
-
|
|
550
|
-
@param literal The literal to use
|
|
551
|
-
|
|
552
|
-
@returns A function that will return true iff the condition is passed
|
|
553
|
-
**--]]
|
|
554
|
-
function t.literal(...)
|
|
555
|
-
local size = select("#", ...)
|
|
556
|
-
if size == 1 then
|
|
557
|
-
local literal = ...
|
|
558
|
-
return function(value)
|
|
559
|
-
if value ~= literal then
|
|
560
|
-
return false, string.format("expected %s, got %s", tostring(literal), tostring(value))
|
|
561
|
-
end
|
|
562
|
-
|
|
563
|
-
return true
|
|
564
|
-
end
|
|
565
|
-
else
|
|
566
|
-
local literals = {}
|
|
567
|
-
for i = 1, size do
|
|
568
|
-
local value = select(i, ...)
|
|
569
|
-
literals[i] = t.literal(value)
|
|
570
|
-
end
|
|
571
|
-
|
|
572
|
-
return t.unionList(literals)
|
|
573
|
-
end
|
|
574
|
-
end
|
|
575
|
-
|
|
576
|
-
--[[**
|
|
577
|
-
DEPRECATED
|
|
578
|
-
Please use t.literal
|
|
579
|
-
**--]]
|
|
580
|
-
t.exactly = t.literal
|
|
581
|
-
|
|
582
|
-
--[[**
|
|
583
|
-
Returns a t.union of each key in the table as a t.literal
|
|
584
|
-
|
|
585
|
-
@param keyTable The table to get keys from
|
|
586
|
-
|
|
587
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
588
|
-
**--]]
|
|
589
|
-
function t.keyOf(keyTable)
|
|
590
|
-
local keys = {}
|
|
591
|
-
local length = 0
|
|
592
|
-
for key in pairs(keyTable) do
|
|
593
|
-
length = length + 1
|
|
594
|
-
keys[length] = key
|
|
595
|
-
end
|
|
596
|
-
|
|
597
|
-
return t.literal(table.unpack(keys, 1, length))
|
|
598
|
-
end
|
|
599
|
-
|
|
600
|
-
--[[**
|
|
601
|
-
Returns a t.union of each value in the table as a t.literal
|
|
602
|
-
|
|
603
|
-
@param valueTable The table to get values from
|
|
604
|
-
|
|
605
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
606
|
-
**--]]
|
|
607
|
-
function t.valueOf(valueTable)
|
|
608
|
-
local values = {}
|
|
609
|
-
local length = 0
|
|
610
|
-
for _, value in pairs(valueTable) do
|
|
611
|
-
length = length + 1
|
|
612
|
-
values[length] = value
|
|
613
|
-
end
|
|
614
|
-
|
|
615
|
-
return t.literal(table.unpack(values, 1, length))
|
|
616
|
-
end
|
|
617
|
-
|
|
618
|
-
--[[**
|
|
619
|
-
ensures value is an integer
|
|
620
|
-
|
|
621
|
-
@param value The value to check against
|
|
622
|
-
|
|
623
|
-
@returns True iff the condition is satisfied, false otherwise
|
|
624
|
-
**--]]
|
|
625
|
-
function t.integer(value)
|
|
626
|
-
local success, errMsg = t.number(value)
|
|
627
|
-
if not success then
|
|
628
|
-
return false, errMsg or ""
|
|
629
|
-
end
|
|
630
|
-
|
|
631
|
-
if value % 1 == 0 then
|
|
632
|
-
return true
|
|
633
|
-
else
|
|
634
|
-
return false, string.format("integer expected, got %s", value)
|
|
635
|
-
end
|
|
636
|
-
end
|
|
637
|
-
|
|
638
|
-
--[[**
|
|
639
|
-
ensures value is a number where min <= value
|
|
640
|
-
|
|
641
|
-
@param min The minimum to use
|
|
642
|
-
|
|
643
|
-
@returns A function that will return true iff the condition is passed
|
|
644
|
-
**--]]
|
|
645
|
-
function t.numberMin(min)
|
|
646
|
-
return function(value)
|
|
647
|
-
local success, errMsg = t.number(value)
|
|
648
|
-
if not success then
|
|
649
|
-
return false, errMsg or ""
|
|
650
|
-
end
|
|
651
|
-
|
|
652
|
-
if value >= min then
|
|
653
|
-
return true
|
|
654
|
-
else
|
|
655
|
-
return false, string.format("number >= %s expected, got %s", min, value)
|
|
656
|
-
end
|
|
657
|
-
end
|
|
658
|
-
end
|
|
659
|
-
|
|
660
|
-
--[[**
|
|
661
|
-
ensures value is a number where value <= max
|
|
662
|
-
|
|
663
|
-
@param max The maximum to use
|
|
664
|
-
|
|
665
|
-
@returns A function that will return true iff the condition is passed
|
|
666
|
-
**--]]
|
|
667
|
-
function t.numberMax(max)
|
|
668
|
-
return function(value)
|
|
669
|
-
local success, errMsg = t.number(value)
|
|
670
|
-
if not success then
|
|
671
|
-
return false, errMsg
|
|
672
|
-
end
|
|
673
|
-
|
|
674
|
-
if value <= max then
|
|
675
|
-
return true
|
|
676
|
-
else
|
|
677
|
-
return false, string.format("number <= %s expected, got %s", max, value)
|
|
678
|
-
end
|
|
679
|
-
end
|
|
680
|
-
end
|
|
681
|
-
|
|
682
|
-
--[[**
|
|
683
|
-
ensures value is a number where min < value
|
|
684
|
-
|
|
685
|
-
@param min The minimum to use
|
|
686
|
-
|
|
687
|
-
@returns A function that will return true iff the condition is passed
|
|
688
|
-
**--]]
|
|
689
|
-
function t.numberMinExclusive(min)
|
|
690
|
-
return function(value)
|
|
691
|
-
local success, errMsg = t.number(value)
|
|
692
|
-
if not success then
|
|
693
|
-
return false, errMsg or ""
|
|
694
|
-
end
|
|
695
|
-
|
|
696
|
-
if min < value then
|
|
697
|
-
return true
|
|
698
|
-
else
|
|
699
|
-
return false, string.format("number > %s expected, got %s", min, value)
|
|
700
|
-
end
|
|
701
|
-
end
|
|
702
|
-
end
|
|
703
|
-
|
|
704
|
-
--[[**
|
|
705
|
-
ensures value is a number where value < max
|
|
706
|
-
|
|
707
|
-
@param max The maximum to use
|
|
708
|
-
|
|
709
|
-
@returns A function that will return true iff the condition is passed
|
|
710
|
-
**--]]
|
|
711
|
-
function t.numberMaxExclusive(max)
|
|
712
|
-
return function(value)
|
|
713
|
-
local success, errMsg = t.number(value)
|
|
714
|
-
if not success then
|
|
715
|
-
return false, errMsg or ""
|
|
716
|
-
end
|
|
717
|
-
|
|
718
|
-
if value < max then
|
|
719
|
-
return true
|
|
720
|
-
else
|
|
721
|
-
return false, string.format("number < %s expected, got %s", max, value)
|
|
722
|
-
end
|
|
723
|
-
end
|
|
724
|
-
end
|
|
725
|
-
|
|
726
|
-
--[[**
|
|
727
|
-
ensures value is a number where value > 0
|
|
728
|
-
|
|
729
|
-
@returns A function that will return true iff the condition is passed
|
|
730
|
-
**--]]
|
|
731
|
-
t.numberPositive = t.numberMinExclusive(0)
|
|
732
|
-
|
|
733
|
-
--[[**
|
|
734
|
-
ensures value is a number where value < 0
|
|
735
|
-
|
|
736
|
-
@returns A function that will return true iff the condition is passed
|
|
737
|
-
**--]]
|
|
738
|
-
t.numberNegative = t.numberMaxExclusive(0)
|
|
739
|
-
|
|
740
|
-
--[[**
|
|
741
|
-
ensures value is a number where min <= value <= max
|
|
742
|
-
|
|
743
|
-
@param min The minimum to use
|
|
744
|
-
@param max The maximum to use
|
|
745
|
-
|
|
746
|
-
@returns A function that will return true iff the condition is passed
|
|
747
|
-
**--]]
|
|
748
|
-
function t.numberConstrained(min, max)
|
|
749
|
-
assert(t.number(min))
|
|
750
|
-
assert(t.number(max))
|
|
751
|
-
local minCheck = t.numberMin(min)
|
|
752
|
-
local maxCheck = t.numberMax(max)
|
|
753
|
-
|
|
754
|
-
return function(value)
|
|
755
|
-
local minSuccess, minErrMsg = minCheck(value)
|
|
756
|
-
if not minSuccess then
|
|
757
|
-
return false, minErrMsg or ""
|
|
758
|
-
end
|
|
759
|
-
|
|
760
|
-
local maxSuccess, maxErrMsg = maxCheck(value)
|
|
761
|
-
if not maxSuccess then
|
|
762
|
-
return false, maxErrMsg or ""
|
|
763
|
-
end
|
|
764
|
-
|
|
765
|
-
return true
|
|
766
|
-
end
|
|
767
|
-
end
|
|
768
|
-
|
|
769
|
-
--[[**
|
|
770
|
-
ensures value is a number where min < value < max
|
|
771
|
-
|
|
772
|
-
@param min The minimum to use
|
|
773
|
-
@param max The maximum to use
|
|
774
|
-
|
|
775
|
-
@returns A function that will return true iff the condition is passed
|
|
776
|
-
**--]]
|
|
777
|
-
function t.numberConstrainedExclusive(min, max)
|
|
778
|
-
assert(t.number(min))
|
|
779
|
-
assert(t.number(max))
|
|
780
|
-
local minCheck = t.numberMinExclusive(min)
|
|
781
|
-
local maxCheck = t.numberMaxExclusive(max)
|
|
782
|
-
|
|
783
|
-
return function(value)
|
|
784
|
-
local minSuccess, minErrMsg = minCheck(value)
|
|
785
|
-
if not minSuccess then
|
|
786
|
-
return false, minErrMsg or ""
|
|
787
|
-
end
|
|
788
|
-
|
|
789
|
-
local maxSuccess, maxErrMsg = maxCheck(value)
|
|
790
|
-
if not maxSuccess then
|
|
791
|
-
return false, maxErrMsg or ""
|
|
792
|
-
end
|
|
793
|
-
|
|
794
|
-
return true
|
|
795
|
-
end
|
|
796
|
-
end
|
|
797
|
-
|
|
798
|
-
--[[**
|
|
799
|
-
ensures value matches string pattern
|
|
800
|
-
|
|
801
|
-
@param string pattern to check against
|
|
802
|
-
|
|
803
|
-
@returns A function that will return true iff the condition is passed
|
|
804
|
-
**--]]
|
|
805
|
-
function t.match(pattern)
|
|
806
|
-
assert(t.string(pattern))
|
|
807
|
-
return function(value)
|
|
808
|
-
local stringSuccess, stringErrMsg = t.string(value)
|
|
809
|
-
if not stringSuccess then
|
|
810
|
-
return false, stringErrMsg
|
|
811
|
-
end
|
|
812
|
-
|
|
813
|
-
if string.match(value, pattern) == nil then
|
|
814
|
-
return false, string.format("%q failed to match pattern %q", value, pattern)
|
|
815
|
-
end
|
|
816
|
-
|
|
817
|
-
return true
|
|
818
|
-
end
|
|
819
|
-
end
|
|
820
|
-
|
|
821
|
-
--[[**
|
|
822
|
-
ensures value is either nil or passes check
|
|
823
|
-
|
|
824
|
-
@param check The check to use
|
|
825
|
-
|
|
826
|
-
@returns A function that will return true iff the condition is passed
|
|
827
|
-
**--]]
|
|
828
|
-
function t.optional(check)
|
|
829
|
-
assert(t.callback(check))
|
|
830
|
-
return function(value)
|
|
831
|
-
if value == nil then
|
|
832
|
-
return true
|
|
833
|
-
end
|
|
834
|
-
|
|
835
|
-
local success, errMsg = check(value)
|
|
836
|
-
if success then
|
|
837
|
-
return true
|
|
838
|
-
else
|
|
839
|
-
return false, string.format("(optional) %s", errMsg or "")
|
|
840
|
-
end
|
|
841
|
-
end
|
|
842
|
-
end
|
|
843
|
-
|
|
844
|
-
--[[**
|
|
845
|
-
matches given tuple against tuple type definition
|
|
846
|
-
|
|
847
|
-
@param ... The type definition for the tuples
|
|
848
|
-
|
|
849
|
-
@returns A function that will return true iff the condition is passed
|
|
850
|
-
**--]]
|
|
851
|
-
function t.tuple(...)
|
|
852
|
-
local checks = { ... }
|
|
853
|
-
return function(...)
|
|
854
|
-
local args = { ... }
|
|
855
|
-
for i, check in ipairs(checks) do
|
|
856
|
-
local success, errMsg = check(args[i])
|
|
857
|
-
if success == false then
|
|
858
|
-
return false, string.format("Bad tuple index #%s:\n\t%s", i, errMsg or "")
|
|
859
|
-
end
|
|
860
|
-
end
|
|
861
|
-
|
|
862
|
-
return true
|
|
863
|
-
end
|
|
864
|
-
end
|
|
865
|
-
|
|
866
|
-
--[[**
|
|
867
|
-
ensures all keys in given table pass check
|
|
868
|
-
|
|
869
|
-
@param check The function to use to check the keys
|
|
870
|
-
|
|
871
|
-
@returns A function that will return true iff the condition is passed
|
|
872
|
-
**--]]
|
|
873
|
-
function t.keys(check)
|
|
874
|
-
assert(t.callback(check))
|
|
875
|
-
return function(value)
|
|
876
|
-
local tableSuccess, tableErrMsg = t.table(value)
|
|
877
|
-
if tableSuccess == false then
|
|
878
|
-
return false, tableErrMsg or ""
|
|
879
|
-
end
|
|
880
|
-
|
|
881
|
-
for key in pairs(value) do
|
|
882
|
-
local success, errMsg = check(key)
|
|
883
|
-
if success == false then
|
|
884
|
-
return false, string.format("bad key %s:\n\t%s", tostring(key), errMsg or "")
|
|
885
|
-
end
|
|
886
|
-
end
|
|
887
|
-
|
|
888
|
-
return true
|
|
889
|
-
end
|
|
890
|
-
end
|
|
891
|
-
|
|
892
|
-
--[[**
|
|
893
|
-
ensures all values in given table pass check
|
|
894
|
-
|
|
895
|
-
@param check The function to use to check the values
|
|
896
|
-
|
|
897
|
-
@returns A function that will return true iff the condition is passed
|
|
898
|
-
**--]]
|
|
899
|
-
function t.values(check)
|
|
900
|
-
assert(t.callback(check))
|
|
901
|
-
return function(value)
|
|
902
|
-
local tableSuccess, tableErrMsg = t.table(value)
|
|
903
|
-
if tableSuccess == false then
|
|
904
|
-
return false, tableErrMsg or ""
|
|
905
|
-
end
|
|
906
|
-
|
|
907
|
-
for key, val in pairs(value) do
|
|
908
|
-
local success, errMsg = check(val)
|
|
909
|
-
if success == false then
|
|
910
|
-
return false, string.format("bad value for key %s:\n\t%s", tostring(key), errMsg or "")
|
|
911
|
-
end
|
|
912
|
-
end
|
|
913
|
-
|
|
914
|
-
return true
|
|
915
|
-
end
|
|
916
|
-
end
|
|
917
|
-
|
|
918
|
-
--[[**
|
|
919
|
-
ensures value is a table and all keys pass keyCheck and all values pass valueCheck
|
|
920
|
-
|
|
921
|
-
@param keyCheck The function to use to check the keys
|
|
922
|
-
@param valueCheck The function to use to check the values
|
|
923
|
-
|
|
924
|
-
@returns A function that will return true iff the condition is passed
|
|
925
|
-
**--]]
|
|
926
|
-
function t.map(keyCheck, valueCheck)
|
|
927
|
-
assert(t.callback(keyCheck))
|
|
928
|
-
assert(t.callback(valueCheck))
|
|
929
|
-
local keyChecker = t.keys(keyCheck)
|
|
930
|
-
local valueChecker = t.values(valueCheck)
|
|
931
|
-
|
|
932
|
-
return function(value)
|
|
933
|
-
local keySuccess, keyErr = keyChecker(value)
|
|
934
|
-
if not keySuccess then
|
|
935
|
-
return false, keyErr or ""
|
|
936
|
-
end
|
|
937
|
-
|
|
938
|
-
local valueSuccess, valueErr = valueChecker(value)
|
|
939
|
-
if not valueSuccess then
|
|
940
|
-
return false, valueErr or ""
|
|
941
|
-
end
|
|
942
|
-
|
|
943
|
-
return true
|
|
944
|
-
end
|
|
945
|
-
end
|
|
946
|
-
|
|
947
|
-
--[[**
|
|
948
|
-
ensures value is a table and all keys pass valueCheck and all values are true
|
|
949
|
-
|
|
950
|
-
@param valueCheck The function to use to check the values
|
|
951
|
-
|
|
952
|
-
@returns A function that will return true iff the condition is passed
|
|
953
|
-
**--]]
|
|
954
|
-
function t.set(valueCheck)
|
|
955
|
-
return t.map(valueCheck, t.literal(true))
|
|
956
|
-
end
|
|
957
|
-
|
|
958
|
-
do
|
|
959
|
-
local arrayKeysCheck = t.keys(t.integer)
|
|
960
|
-
--[[**
|
|
961
|
-
ensures value is an array and all values of the array match check
|
|
962
|
-
|
|
963
|
-
@param check The check to compare all values with
|
|
964
|
-
|
|
965
|
-
@returns A function that will return true iff the condition is passed
|
|
966
|
-
**--]]
|
|
967
|
-
function t.array(check)
|
|
968
|
-
assert(t.callback(check))
|
|
969
|
-
local valuesCheck = t.values(check)
|
|
970
|
-
|
|
971
|
-
return function(value)
|
|
972
|
-
local keySuccess, keyErrMsg = arrayKeysCheck(value)
|
|
973
|
-
if keySuccess == false then
|
|
974
|
-
return false, string.format("[array] %s", keyErrMsg or "")
|
|
975
|
-
end
|
|
976
|
-
|
|
977
|
-
-- # is unreliable for sparse arrays
|
|
978
|
-
-- Count upwards using ipairs to avoid false positives from the behavior of #
|
|
979
|
-
local arraySize = 0
|
|
980
|
-
|
|
981
|
-
for _ in ipairs(value) do
|
|
982
|
-
arraySize = arraySize + 1
|
|
983
|
-
end
|
|
984
|
-
|
|
985
|
-
for key in pairs(value) do
|
|
986
|
-
if key < 1 or key > arraySize then
|
|
987
|
-
return false, string.format("[array] key %s must be sequential", tostring(key))
|
|
988
|
-
end
|
|
989
|
-
end
|
|
990
|
-
|
|
991
|
-
local valueSuccess, valueErrMsg = valuesCheck(value)
|
|
992
|
-
if not valueSuccess then
|
|
993
|
-
return false, string.format("[array] %s", valueErrMsg or "")
|
|
994
|
-
end
|
|
995
|
-
|
|
996
|
-
return true
|
|
997
|
-
end
|
|
998
|
-
end
|
|
999
|
-
|
|
1000
|
-
--[[**
|
|
1001
|
-
ensures value is an array of a strict makeup and size
|
|
1002
|
-
|
|
1003
|
-
@param check The check to compare all values with
|
|
1004
|
-
|
|
1005
|
-
@returns A function that will return true iff the condition is passed
|
|
1006
|
-
**--]]
|
|
1007
|
-
function t.strictArray(...)
|
|
1008
|
-
local valueTypes = { ... }
|
|
1009
|
-
assert(t.array(t.callback)(valueTypes))
|
|
1010
|
-
|
|
1011
|
-
return function(value)
|
|
1012
|
-
local keySuccess, keyErrMsg = arrayKeysCheck(value)
|
|
1013
|
-
if keySuccess == false then
|
|
1014
|
-
return false, string.format("[strictArray] %s", keyErrMsg or "")
|
|
1015
|
-
end
|
|
1016
|
-
|
|
1017
|
-
-- If there's more than the set array size, disallow
|
|
1018
|
-
if #valueTypes < #value then
|
|
1019
|
-
return false, string.format("[strictArray] Array size exceeds limit of %d", #valueTypes)
|
|
1020
|
-
end
|
|
1021
|
-
|
|
1022
|
-
for idx, typeFn in pairs(valueTypes) do
|
|
1023
|
-
local typeSuccess, typeErrMsg = typeFn(value[idx])
|
|
1024
|
-
if not typeSuccess then
|
|
1025
|
-
return false, string.format("[strictArray] Array index #%d - %s", idx, typeErrMsg)
|
|
1026
|
-
end
|
|
1027
|
-
end
|
|
1028
|
-
|
|
1029
|
-
return true
|
|
1030
|
-
end
|
|
1031
|
-
end
|
|
1032
|
-
end
|
|
1033
|
-
|
|
1034
|
-
do
|
|
1035
|
-
local callbackArray = t.array(t.callback)
|
|
1036
|
-
--[[**
|
|
1037
|
-
creates a union type
|
|
1038
|
-
|
|
1039
|
-
@param checks The checks to union
|
|
1040
|
-
|
|
1041
|
-
@returns A function that will return true iff the condition is passed
|
|
1042
|
-
**--]]
|
|
1043
|
-
function t.unionList(checks)
|
|
1044
|
-
assert(callbackArray(checks))
|
|
1045
|
-
|
|
1046
|
-
return function(value)
|
|
1047
|
-
for _, check in ipairs(checks) do
|
|
1048
|
-
if check(value) then
|
|
1049
|
-
return true
|
|
1050
|
-
end
|
|
1051
|
-
end
|
|
1052
|
-
|
|
1053
|
-
return false, "bad type for union"
|
|
1054
|
-
end
|
|
1055
|
-
end
|
|
1056
|
-
|
|
1057
|
-
--[[**
|
|
1058
|
-
creates a union type
|
|
1059
|
-
|
|
1060
|
-
@param ... The checks to union
|
|
1061
|
-
|
|
1062
|
-
@returns A function that will return true iff the condition is passed
|
|
1063
|
-
**--]]
|
|
1064
|
-
function t.union(...)
|
|
1065
|
-
return t.unionList({ ... })
|
|
1066
|
-
end
|
|
1067
|
-
|
|
1068
|
-
--[[**
|
|
1069
|
-
Alias for t.union
|
|
1070
|
-
**--]]
|
|
1071
|
-
t.some = t.union
|
|
1072
|
-
|
|
1073
|
-
--[[**
|
|
1074
|
-
creates an intersection type
|
|
1075
|
-
|
|
1076
|
-
@param checks The checks to intersect
|
|
1077
|
-
|
|
1078
|
-
@returns A function that will return true iff the condition is passed
|
|
1079
|
-
**--]]
|
|
1080
|
-
function t.intersectionList(checks)
|
|
1081
|
-
assert(callbackArray(checks))
|
|
1082
|
-
|
|
1083
|
-
return function(value)
|
|
1084
|
-
for _, check in ipairs(checks) do
|
|
1085
|
-
local success, errMsg = check(value)
|
|
1086
|
-
if not success then
|
|
1087
|
-
return false, errMsg or ""
|
|
1088
|
-
end
|
|
1089
|
-
end
|
|
1090
|
-
|
|
1091
|
-
return true
|
|
1092
|
-
end
|
|
1093
|
-
end
|
|
1094
|
-
|
|
1095
|
-
--[[**
|
|
1096
|
-
creates an intersection type
|
|
1097
|
-
|
|
1098
|
-
@param ... The checks to intersect
|
|
1099
|
-
|
|
1100
|
-
@returns A function that will return true iff the condition is passed
|
|
1101
|
-
**--]]
|
|
1102
|
-
function t.intersection(...)
|
|
1103
|
-
return t.intersectionList({ ... })
|
|
1104
|
-
end
|
|
1105
|
-
|
|
1106
|
-
--[[**
|
|
1107
|
-
Alias for t.intersection
|
|
1108
|
-
**--]]
|
|
1109
|
-
t.every = t.intersection
|
|
1110
|
-
end
|
|
1111
|
-
|
|
1112
|
-
do
|
|
1113
|
-
local checkInterface = t.map(t.any, t.callback)
|
|
1114
|
-
--[[**
|
|
1115
|
-
ensures value matches given interface definition
|
|
1116
|
-
|
|
1117
|
-
@param checkTable The interface definition
|
|
1118
|
-
|
|
1119
|
-
@returns A function that will return true iff the condition is passed
|
|
1120
|
-
**--]]
|
|
1121
|
-
function t.interface(checkTable)
|
|
1122
|
-
assert(checkInterface(checkTable))
|
|
1123
|
-
return function(value)
|
|
1124
|
-
local tableSuccess, tableErrMsg = t.table(value)
|
|
1125
|
-
if tableSuccess == false then
|
|
1126
|
-
return false, tableErrMsg or ""
|
|
1127
|
-
end
|
|
1128
|
-
|
|
1129
|
-
for key, check in pairs(checkTable) do
|
|
1130
|
-
local success, errMsg = check(value[key])
|
|
1131
|
-
if success == false then
|
|
1132
|
-
return false, string.format("[interface] bad value for %s:\n\t%s", tostring(key), errMsg or "")
|
|
1133
|
-
end
|
|
1134
|
-
end
|
|
1135
|
-
|
|
1136
|
-
return true
|
|
1137
|
-
end
|
|
1138
|
-
end
|
|
1139
|
-
|
|
1140
|
-
--[[**
|
|
1141
|
-
ensures value matches given interface definition strictly
|
|
1142
|
-
|
|
1143
|
-
@param checkTable The interface definition
|
|
1144
|
-
|
|
1145
|
-
@returns A function that will return true iff the condition is passed
|
|
1146
|
-
**--]]
|
|
1147
|
-
function t.strictInterface(checkTable)
|
|
1148
|
-
assert(checkInterface(checkTable))
|
|
1149
|
-
return function(value)
|
|
1150
|
-
local tableSuccess, tableErrMsg = t.table(value)
|
|
1151
|
-
if tableSuccess == false then
|
|
1152
|
-
return false, tableErrMsg or ""
|
|
1153
|
-
end
|
|
1154
|
-
|
|
1155
|
-
for key, check in pairs(checkTable) do
|
|
1156
|
-
local success, errMsg = check(value[key])
|
|
1157
|
-
if success == false then
|
|
1158
|
-
return false, string.format("[interface] bad value for %s:\n\t%s", tostring(key), errMsg or "")
|
|
1159
|
-
end
|
|
1160
|
-
end
|
|
1161
|
-
|
|
1162
|
-
for key in pairs(value) do
|
|
1163
|
-
if not checkTable[key] then
|
|
1164
|
-
return false, string.format("[interface] unexpected field %q", tostring(key))
|
|
1165
|
-
end
|
|
1166
|
-
end
|
|
1167
|
-
|
|
1168
|
-
return true
|
|
1169
|
-
end
|
|
1170
|
-
end
|
|
1171
|
-
end
|
|
1172
|
-
|
|
1173
|
-
--[[**
|
|
1174
|
-
ensure value is an Instance and it's ClassName matches the given ClassName
|
|
1175
|
-
|
|
1176
|
-
@param className The class name to check for
|
|
1177
|
-
|
|
1178
|
-
@returns A function that will return true iff the condition is passed
|
|
1179
|
-
**--]]
|
|
1180
|
-
function t.instanceOf(className, childTable)
|
|
1181
|
-
assert(t.string(className))
|
|
1182
|
-
|
|
1183
|
-
local childrenCheck
|
|
1184
|
-
if childTable ~= nil then
|
|
1185
|
-
childrenCheck = t.children(childTable)
|
|
1186
|
-
end
|
|
1187
|
-
|
|
1188
|
-
return function(value)
|
|
1189
|
-
local instanceSuccess, instanceErrMsg = t.Instance(value)
|
|
1190
|
-
if not instanceSuccess then
|
|
1191
|
-
return false, instanceErrMsg or ""
|
|
1192
|
-
end
|
|
1193
|
-
|
|
1194
|
-
if value.ClassName ~= className then
|
|
1195
|
-
return false, string.format("%s expected, got %s", className, value.ClassName)
|
|
1196
|
-
end
|
|
1197
|
-
|
|
1198
|
-
if childrenCheck then
|
|
1199
|
-
local childrenSuccess, childrenErrMsg = childrenCheck(value)
|
|
1200
|
-
if not childrenSuccess then
|
|
1201
|
-
return false, childrenErrMsg
|
|
1202
|
-
end
|
|
1203
|
-
end
|
|
1204
|
-
|
|
1205
|
-
return true
|
|
1206
|
-
end
|
|
1207
|
-
end
|
|
1208
|
-
|
|
1209
|
-
t.instance = t.instanceOf
|
|
1210
|
-
|
|
1211
|
-
--[[**
|
|
1212
|
-
ensure value is an Instance and it's ClassName matches the given ClassName by an IsA comparison
|
|
1213
|
-
|
|
1214
|
-
@param className The class name to check for
|
|
1215
|
-
|
|
1216
|
-
@returns A function that will return true iff the condition is passed
|
|
1217
|
-
**--]]
|
|
1218
|
-
function t.instanceIsA(className, childTable)
|
|
1219
|
-
assert(t.string(className))
|
|
1220
|
-
|
|
1221
|
-
local childrenCheck
|
|
1222
|
-
if childTable ~= nil then
|
|
1223
|
-
childrenCheck = t.children(childTable)
|
|
1224
|
-
end
|
|
1225
|
-
|
|
1226
|
-
return function(value)
|
|
1227
|
-
local instanceSuccess, instanceErrMsg = t.Instance(value)
|
|
1228
|
-
if not instanceSuccess then
|
|
1229
|
-
return false, instanceErrMsg or ""
|
|
1230
|
-
end
|
|
1231
|
-
|
|
1232
|
-
if not value:IsA(className) then
|
|
1233
|
-
return false, string.format("%s expected, got %s", className, value.ClassName)
|
|
1234
|
-
end
|
|
1235
|
-
|
|
1236
|
-
if childrenCheck then
|
|
1237
|
-
local childrenSuccess, childrenErrMsg = childrenCheck(value)
|
|
1238
|
-
if not childrenSuccess then
|
|
1239
|
-
return false, childrenErrMsg
|
|
1240
|
-
end
|
|
1241
|
-
end
|
|
1242
|
-
|
|
1243
|
-
return true
|
|
1244
|
-
end
|
|
1245
|
-
end
|
|
1246
|
-
|
|
1247
|
-
--[[**
|
|
1248
|
-
ensures value is an enum of the correct type
|
|
1249
|
-
|
|
1250
|
-
@param enum The enum to check
|
|
1251
|
-
|
|
1252
|
-
@returns A function that will return true iff the condition is passed
|
|
1253
|
-
**--]]
|
|
1254
|
-
function t.enum(enum)
|
|
1255
|
-
assert(t.Enum(enum))
|
|
1256
|
-
return function(value)
|
|
1257
|
-
local enumItemSuccess, enumItemErrMsg = t.EnumItem(value)
|
|
1258
|
-
if not enumItemSuccess then
|
|
1259
|
-
return false, enumItemErrMsg
|
|
1260
|
-
end
|
|
1261
|
-
|
|
1262
|
-
if value.EnumType == enum then
|
|
1263
|
-
return true
|
|
1264
|
-
else
|
|
1265
|
-
return false, string.format("enum of %s expected, got enum of %s", tostring(enum), tostring(value.EnumType))
|
|
1266
|
-
end
|
|
1267
|
-
end
|
|
1268
|
-
end
|
|
1269
|
-
|
|
1270
|
-
do
|
|
1271
|
-
local checkWrap = t.tuple(t.callback, t.callback)
|
|
1272
|
-
|
|
1273
|
-
--[[**
|
|
1274
|
-
wraps a callback in an assert with checkArgs
|
|
1275
|
-
|
|
1276
|
-
@param callback The function to wrap
|
|
1277
|
-
@param checkArgs The function to use to check arguments in the assert
|
|
1278
|
-
|
|
1279
|
-
@returns A function that first asserts using checkArgs and then calls callback
|
|
1280
|
-
**--]]
|
|
1281
|
-
function t.wrap(callback, checkArgs)
|
|
1282
|
-
assert(checkWrap(callback, checkArgs))
|
|
1283
|
-
return function(...)
|
|
1284
|
-
assert(checkArgs(...))
|
|
1285
|
-
return callback(...)
|
|
1286
|
-
end
|
|
1287
|
-
end
|
|
1288
|
-
end
|
|
1289
|
-
|
|
1290
|
-
--[[**
|
|
1291
|
-
asserts a given check
|
|
1292
|
-
|
|
1293
|
-
@param check The function to wrap with an assert
|
|
1294
|
-
|
|
1295
|
-
@returns A function that simply wraps the given check in an assert
|
|
1296
|
-
**--]]
|
|
1297
|
-
function t.strict(check)
|
|
1298
|
-
return function(...)
|
|
1299
|
-
assert(check(...))
|
|
1300
|
-
end
|
|
1301
|
-
end
|
|
1302
|
-
|
|
1303
|
-
do
|
|
1304
|
-
local checkChildren = t.map(t.string, t.callback)
|
|
1305
|
-
|
|
1306
|
-
--[[**
|
|
1307
|
-
Takes a table where keys are child names and values are functions to check the children against.
|
|
1308
|
-
Pass an instance tree into the function.
|
|
1309
|
-
If at least one child passes each check, the overall check passes.
|
|
1310
|
-
|
|
1311
|
-
Warning! If you pass in a tree with more than one child of the same name, this function will always return false
|
|
1312
|
-
|
|
1313
|
-
@param checkTable The table to check against
|
|
1314
|
-
|
|
1315
|
-
@returns A function that checks an instance tree
|
|
1316
|
-
**--]]
|
|
1317
|
-
function t.children(checkTable)
|
|
1318
|
-
assert(checkChildren(checkTable))
|
|
1319
|
-
|
|
1320
|
-
return function(value)
|
|
1321
|
-
local instanceSuccess, instanceErrMsg = t.Instance(value)
|
|
1322
|
-
if not instanceSuccess then
|
|
1323
|
-
return false, instanceErrMsg or ""
|
|
1324
|
-
end
|
|
1325
|
-
|
|
1326
|
-
local childrenByName = {}
|
|
1327
|
-
for _, child in ipairs(value:GetChildren()) do
|
|
1328
|
-
local name = child.Name
|
|
1329
|
-
if checkTable[name] then
|
|
1330
|
-
if childrenByName[name] then
|
|
1331
|
-
return false, string.format("Cannot process multiple children with the same name %q", name)
|
|
1332
|
-
end
|
|
1333
|
-
|
|
1334
|
-
childrenByName[name] = child
|
|
1335
|
-
end
|
|
1336
|
-
end
|
|
1337
|
-
|
|
1338
|
-
for name, check in pairs(checkTable) do
|
|
1339
|
-
local success, errMsg = check(childrenByName[name])
|
|
1340
|
-
if not success then
|
|
1341
|
-
return false, string.format("[%s.%s] %s", value:GetFullName(), name, errMsg or "")
|
|
1342
|
-
end
|
|
1343
|
-
end
|
|
1344
|
-
|
|
1345
|
-
return true
|
|
1346
|
-
end
|
|
1347
|
-
end
|
|
1348
|
-
end
|
|
1349
|
-
|
|
1350
|
-
return t
|
|
1
|
+
-- t: a runtime typechecker for Roblox
|
|
2
|
+
|
|
3
|
+
local t = {}
|
|
4
|
+
|
|
5
|
+
function t.type(typeName)
|
|
6
|
+
return function(value)
|
|
7
|
+
local valueType = type(value)
|
|
8
|
+
if valueType == typeName then
|
|
9
|
+
return true
|
|
10
|
+
else
|
|
11
|
+
return false, string.format("%s expected, got %s", typeName, valueType)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
function t.typeof(typeName)
|
|
17
|
+
return function(value)
|
|
18
|
+
local valueType = typeof(value)
|
|
19
|
+
if valueType == typeName then
|
|
20
|
+
return true
|
|
21
|
+
else
|
|
22
|
+
return false, string.format("%s expected, got %s", typeName, valueType)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
--[[**
|
|
28
|
+
matches any type except nil
|
|
29
|
+
|
|
30
|
+
@param value The value to check against
|
|
31
|
+
|
|
32
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
33
|
+
**--]]
|
|
34
|
+
function t.any(value)
|
|
35
|
+
if value ~= nil then
|
|
36
|
+
return true
|
|
37
|
+
else
|
|
38
|
+
return false, "any expected, got nil"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
--Lua primitives
|
|
43
|
+
|
|
44
|
+
--[[**
|
|
45
|
+
ensures Lua primitive boolean type
|
|
46
|
+
|
|
47
|
+
@param value The value to check against
|
|
48
|
+
|
|
49
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
50
|
+
**--]]
|
|
51
|
+
t.boolean = t.typeof("boolean")
|
|
52
|
+
|
|
53
|
+
--[[**
|
|
54
|
+
ensures Lua primitive buffer type
|
|
55
|
+
|
|
56
|
+
@param value The value to check against
|
|
57
|
+
|
|
58
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
59
|
+
**--]]
|
|
60
|
+
t.buffer = t.typeof("buffer")
|
|
61
|
+
|
|
62
|
+
--[[**
|
|
63
|
+
ensures Lua primitive thread type
|
|
64
|
+
|
|
65
|
+
@param value The value to check against
|
|
66
|
+
|
|
67
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
68
|
+
**--]]
|
|
69
|
+
t.thread = t.typeof("thread")
|
|
70
|
+
|
|
71
|
+
--[[**
|
|
72
|
+
ensures Lua primitive callback type
|
|
73
|
+
|
|
74
|
+
@param value The value to check against
|
|
75
|
+
|
|
76
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
77
|
+
**--]]
|
|
78
|
+
t.callback = t.typeof("function")
|
|
79
|
+
t["function"] = t.callback
|
|
80
|
+
|
|
81
|
+
--[[**
|
|
82
|
+
ensures Lua primitive none type
|
|
83
|
+
|
|
84
|
+
@param value The value to check against
|
|
85
|
+
|
|
86
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
87
|
+
**--]]
|
|
88
|
+
t.none = t.typeof("nil")
|
|
89
|
+
t["nil"] = t.none
|
|
90
|
+
|
|
91
|
+
--[[**
|
|
92
|
+
ensures Lua primitive string type
|
|
93
|
+
|
|
94
|
+
@param value The value to check against
|
|
95
|
+
|
|
96
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
97
|
+
**--]]
|
|
98
|
+
t.string = t.typeof("string")
|
|
99
|
+
|
|
100
|
+
--[[**
|
|
101
|
+
ensures Lua primitive table type
|
|
102
|
+
|
|
103
|
+
@param value The value to check against
|
|
104
|
+
|
|
105
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
106
|
+
**--]]
|
|
107
|
+
t.table = t.typeof("table")
|
|
108
|
+
|
|
109
|
+
--[[**
|
|
110
|
+
ensures Lua primitive userdata type
|
|
111
|
+
|
|
112
|
+
@param value The value to check against
|
|
113
|
+
|
|
114
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
115
|
+
**--]]
|
|
116
|
+
t.userdata = t.type("userdata")
|
|
117
|
+
|
|
118
|
+
--[[**
|
|
119
|
+
ensures Lua primitive vector type
|
|
120
|
+
|
|
121
|
+
@param value The value to check against
|
|
122
|
+
|
|
123
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
124
|
+
**--]]
|
|
125
|
+
t.vector = t.type("vector")
|
|
126
|
+
|
|
127
|
+
--[[**
|
|
128
|
+
ensures value is a number and non-NaN
|
|
129
|
+
|
|
130
|
+
@param value The value to check against
|
|
131
|
+
|
|
132
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
133
|
+
**--]]
|
|
134
|
+
function t.number(value)
|
|
135
|
+
local valueType = typeof(value)
|
|
136
|
+
if valueType == "number" then
|
|
137
|
+
if value == value then
|
|
138
|
+
return true
|
|
139
|
+
else
|
|
140
|
+
return false, "unexpected NaN value"
|
|
141
|
+
end
|
|
142
|
+
else
|
|
143
|
+
return false, string.format("number expected, got %s", valueType)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
--[[**
|
|
148
|
+
ensures value is NaN
|
|
149
|
+
|
|
150
|
+
@param value The value to check against
|
|
151
|
+
|
|
152
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
153
|
+
**--]]
|
|
154
|
+
function t.nan(value)
|
|
155
|
+
local valueType = typeof(value)
|
|
156
|
+
if valueType == "number" then
|
|
157
|
+
if value ~= value then
|
|
158
|
+
return true
|
|
159
|
+
else
|
|
160
|
+
return false, "unexpected non-NaN value"
|
|
161
|
+
end
|
|
162
|
+
else
|
|
163
|
+
return false, string.format("number expected, got %s", valueType)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
-- roblox types
|
|
168
|
+
|
|
169
|
+
--[[**
|
|
170
|
+
ensures Roblox Axes type
|
|
171
|
+
|
|
172
|
+
@param value The value to check against
|
|
173
|
+
|
|
174
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
175
|
+
**--]]
|
|
176
|
+
t.Axes = t.typeof("Axes")
|
|
177
|
+
|
|
178
|
+
--[[**
|
|
179
|
+
ensures Roblox BrickColor type
|
|
180
|
+
|
|
181
|
+
@param value The value to check against
|
|
182
|
+
|
|
183
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
184
|
+
**--]]
|
|
185
|
+
t.BrickColor = t.typeof("BrickColor")
|
|
186
|
+
|
|
187
|
+
--[[**
|
|
188
|
+
ensures Roblox CatalogSearchParams type
|
|
189
|
+
|
|
190
|
+
@param value The value to check against
|
|
191
|
+
|
|
192
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
193
|
+
**--]]
|
|
194
|
+
t.CatalogSearchParams = t.typeof("CatalogSearchParams")
|
|
195
|
+
|
|
196
|
+
--[[**
|
|
197
|
+
ensures Roblox CFrame type
|
|
198
|
+
|
|
199
|
+
@param value The value to check against
|
|
200
|
+
|
|
201
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
202
|
+
**--]]
|
|
203
|
+
t.CFrame = t.typeof("CFrame")
|
|
204
|
+
|
|
205
|
+
--[[**
|
|
206
|
+
ensures Roblox Content type
|
|
207
|
+
|
|
208
|
+
@param value The value to check against
|
|
209
|
+
|
|
210
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
211
|
+
**--]]
|
|
212
|
+
t.Content = t.typeof("Content")
|
|
213
|
+
|
|
214
|
+
--[[**
|
|
215
|
+
ensures Roblox Color3 type
|
|
216
|
+
|
|
217
|
+
@param value The value to check against
|
|
218
|
+
|
|
219
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
220
|
+
**--]]
|
|
221
|
+
t.Color3 = t.typeof("Color3")
|
|
222
|
+
|
|
223
|
+
--[[**
|
|
224
|
+
ensures Roblox ColorSequence type
|
|
225
|
+
|
|
226
|
+
@param value The value to check against
|
|
227
|
+
|
|
228
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
229
|
+
**--]]
|
|
230
|
+
t.ColorSequence = t.typeof("ColorSequence")
|
|
231
|
+
|
|
232
|
+
--[[**
|
|
233
|
+
ensures Roblox ColorSequenceKeypoint type
|
|
234
|
+
|
|
235
|
+
@param value The value to check against
|
|
236
|
+
|
|
237
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
238
|
+
**--]]
|
|
239
|
+
t.ColorSequenceKeypoint = t.typeof("ColorSequenceKeypoint")
|
|
240
|
+
|
|
241
|
+
--[[**
|
|
242
|
+
ensures Roblox DateTime type
|
|
243
|
+
|
|
244
|
+
@param value The value to check against
|
|
245
|
+
|
|
246
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
247
|
+
**--]]
|
|
248
|
+
t.DateTime = t.typeof("DateTime")
|
|
249
|
+
|
|
250
|
+
--[[**
|
|
251
|
+
ensures Roblox DockWidgetPluginGuiInfo type
|
|
252
|
+
|
|
253
|
+
@param value The value to check against
|
|
254
|
+
|
|
255
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
256
|
+
**--]]
|
|
257
|
+
t.DockWidgetPluginGuiInfo = t.typeof("DockWidgetPluginGuiInfo")
|
|
258
|
+
|
|
259
|
+
--[[**
|
|
260
|
+
ensures Roblox Enum type
|
|
261
|
+
|
|
262
|
+
@param value The value to check against
|
|
263
|
+
|
|
264
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
265
|
+
**--]]
|
|
266
|
+
t.Enum = t.typeof("Enum")
|
|
267
|
+
|
|
268
|
+
--[[**
|
|
269
|
+
ensures Roblox EnumItem type
|
|
270
|
+
|
|
271
|
+
@param value The value to check against
|
|
272
|
+
|
|
273
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
274
|
+
**--]]
|
|
275
|
+
t.EnumItem = t.typeof("EnumItem")
|
|
276
|
+
|
|
277
|
+
--[[**
|
|
278
|
+
ensures Roblox Enums type
|
|
279
|
+
|
|
280
|
+
@param value The value to check against
|
|
281
|
+
|
|
282
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
283
|
+
**--]]
|
|
284
|
+
t.Enums = t.typeof("Enums")
|
|
285
|
+
|
|
286
|
+
--[[**
|
|
287
|
+
ensures Roblox Faces type
|
|
288
|
+
|
|
289
|
+
@param value The value to check against
|
|
290
|
+
|
|
291
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
292
|
+
**--]]
|
|
293
|
+
t.Faces = t.typeof("Faces")
|
|
294
|
+
|
|
295
|
+
--[[**
|
|
296
|
+
ensures Roblox FloatCurveKey type
|
|
297
|
+
|
|
298
|
+
@param value The value to check against
|
|
299
|
+
|
|
300
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
301
|
+
**--]]
|
|
302
|
+
t.FloatCurveKey = t.typeof("FloatCurveKey")
|
|
303
|
+
|
|
304
|
+
--[[**
|
|
305
|
+
ensures Roblox Font type
|
|
306
|
+
|
|
307
|
+
@param value The value to check against
|
|
308
|
+
|
|
309
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
310
|
+
**--]]
|
|
311
|
+
t.Font = t.typeof("Font")
|
|
312
|
+
|
|
313
|
+
--[[**
|
|
314
|
+
ensures Roblox Instance type
|
|
315
|
+
|
|
316
|
+
@param value The value to check against
|
|
317
|
+
|
|
318
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
319
|
+
**--]]
|
|
320
|
+
t.Instance = t.typeof("Instance")
|
|
321
|
+
|
|
322
|
+
--[[**
|
|
323
|
+
ensures Roblox NumberRange type
|
|
324
|
+
|
|
325
|
+
@param value The value to check against
|
|
326
|
+
|
|
327
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
328
|
+
**--]]
|
|
329
|
+
t.NumberRange = t.typeof("NumberRange")
|
|
330
|
+
|
|
331
|
+
--[[**
|
|
332
|
+
ensures Roblox NumberSequence type
|
|
333
|
+
|
|
334
|
+
@param value The value to check against
|
|
335
|
+
|
|
336
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
337
|
+
**--]]
|
|
338
|
+
t.NumberSequence = t.typeof("NumberSequence")
|
|
339
|
+
|
|
340
|
+
--[[**
|
|
341
|
+
ensures Roblox NumberSequenceKeypoint type
|
|
342
|
+
|
|
343
|
+
@param value The value to check against
|
|
344
|
+
|
|
345
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
346
|
+
**--]]
|
|
347
|
+
t.NumberSequenceKeypoint = t.typeof("NumberSequenceKeypoint")
|
|
348
|
+
|
|
349
|
+
--[[**
|
|
350
|
+
ensures Roblox OverlapParams type
|
|
351
|
+
|
|
352
|
+
@param value The value to check against
|
|
353
|
+
|
|
354
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
355
|
+
**--]]
|
|
356
|
+
t.OverlapParams = t.typeof("OverlapParams")
|
|
357
|
+
|
|
358
|
+
--[[**
|
|
359
|
+
ensures Roblox PathWaypoint type
|
|
360
|
+
|
|
361
|
+
@param value The value to check against
|
|
362
|
+
|
|
363
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
364
|
+
**--]]
|
|
365
|
+
t.PathWaypoint = t.typeof("PathWaypoint")
|
|
366
|
+
|
|
367
|
+
--[[**
|
|
368
|
+
ensures Roblox PhysicalProperties type
|
|
369
|
+
|
|
370
|
+
@param value The value to check against
|
|
371
|
+
|
|
372
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
373
|
+
**--]]
|
|
374
|
+
t.PhysicalProperties = t.typeof("PhysicalProperties")
|
|
375
|
+
|
|
376
|
+
--[[**
|
|
377
|
+
ensures Roblox Random type
|
|
378
|
+
|
|
379
|
+
@param value The value to check against
|
|
380
|
+
|
|
381
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
382
|
+
**--]]
|
|
383
|
+
t.Random = t.typeof("Random")
|
|
384
|
+
|
|
385
|
+
--[[**
|
|
386
|
+
ensures Roblox Ray type
|
|
387
|
+
|
|
388
|
+
@param value The value to check against
|
|
389
|
+
|
|
390
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
391
|
+
**--]]
|
|
392
|
+
t.Ray = t.typeof("Ray")
|
|
393
|
+
|
|
394
|
+
--[[**
|
|
395
|
+
ensures Roblox RaycastParams type
|
|
396
|
+
|
|
397
|
+
@param value The value to check against
|
|
398
|
+
|
|
399
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
400
|
+
**--]]
|
|
401
|
+
t.RaycastParams = t.typeof("RaycastParams")
|
|
402
|
+
|
|
403
|
+
--[[**
|
|
404
|
+
ensures Roblox RaycastResult type
|
|
405
|
+
|
|
406
|
+
@param value The value to check against
|
|
407
|
+
|
|
408
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
409
|
+
**--]]
|
|
410
|
+
t.RaycastResult = t.typeof("RaycastResult")
|
|
411
|
+
|
|
412
|
+
--[[**
|
|
413
|
+
ensures Roblox RBXScriptConnection type
|
|
414
|
+
|
|
415
|
+
@param value The value to check against
|
|
416
|
+
|
|
417
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
418
|
+
**--]]
|
|
419
|
+
t.RBXScriptConnection = t.typeof("RBXScriptConnection")
|
|
420
|
+
|
|
421
|
+
--[[**
|
|
422
|
+
ensures Roblox RBXScriptSignal type
|
|
423
|
+
|
|
424
|
+
@param value The value to check against
|
|
425
|
+
|
|
426
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
427
|
+
**--]]
|
|
428
|
+
t.RBXScriptSignal = t.typeof("RBXScriptSignal")
|
|
429
|
+
|
|
430
|
+
--[[**
|
|
431
|
+
ensures Roblox Rect type
|
|
432
|
+
|
|
433
|
+
@param value The value to check against
|
|
434
|
+
|
|
435
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
436
|
+
**--]]
|
|
437
|
+
t.Rect = t.typeof("Rect")
|
|
438
|
+
|
|
439
|
+
--[[**
|
|
440
|
+
ensures Roblox Region3 type
|
|
441
|
+
|
|
442
|
+
@param value The value to check against
|
|
443
|
+
|
|
444
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
445
|
+
**--]]
|
|
446
|
+
t.Region3 = t.typeof("Region3")
|
|
447
|
+
|
|
448
|
+
--[[**
|
|
449
|
+
ensures Roblox Region3int16 type
|
|
450
|
+
|
|
451
|
+
@param value The value to check against
|
|
452
|
+
|
|
453
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
454
|
+
**--]]
|
|
455
|
+
t.Region3int16 = t.typeof("Region3int16")
|
|
456
|
+
|
|
457
|
+
--[[**
|
|
458
|
+
ensures Roblox TweenInfo type
|
|
459
|
+
|
|
460
|
+
@param value The value to check against
|
|
461
|
+
|
|
462
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
463
|
+
**--]]
|
|
464
|
+
t.TweenInfo = t.typeof("TweenInfo")
|
|
465
|
+
|
|
466
|
+
--[[**
|
|
467
|
+
ensures Roblox UDim type
|
|
468
|
+
|
|
469
|
+
@param value The value to check against
|
|
470
|
+
|
|
471
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
472
|
+
**--]]
|
|
473
|
+
t.UDim = t.typeof("UDim")
|
|
474
|
+
|
|
475
|
+
--[[**
|
|
476
|
+
ensures Roblox UDim2 type
|
|
477
|
+
|
|
478
|
+
@param value The value to check against
|
|
479
|
+
|
|
480
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
481
|
+
**--]]
|
|
482
|
+
t.UDim2 = t.typeof("UDim2")
|
|
483
|
+
|
|
484
|
+
--[[**
|
|
485
|
+
ensures Roblox Vector2 type
|
|
486
|
+
|
|
487
|
+
@param value The value to check against
|
|
488
|
+
|
|
489
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
490
|
+
**--]]
|
|
491
|
+
t.Vector2 = t.typeof("Vector2")
|
|
492
|
+
|
|
493
|
+
--[[**
|
|
494
|
+
ensures Roblox Vector2int16 type
|
|
495
|
+
|
|
496
|
+
@param value The value to check against
|
|
497
|
+
|
|
498
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
499
|
+
**--]]
|
|
500
|
+
t.Vector2int16 = t.typeof("Vector2int16")
|
|
501
|
+
|
|
502
|
+
--[[**
|
|
503
|
+
ensures Roblox Vector3 type
|
|
504
|
+
|
|
505
|
+
@param value The value to check against
|
|
506
|
+
|
|
507
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
508
|
+
**--]]
|
|
509
|
+
t.Vector3 = t.typeof("Vector3")
|
|
510
|
+
|
|
511
|
+
--[[**
|
|
512
|
+
ensures Roblox Vector3int16 type
|
|
513
|
+
|
|
514
|
+
@param value The value to check against
|
|
515
|
+
|
|
516
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
517
|
+
**--]]
|
|
518
|
+
t.Vector3int16 = t.typeof("Vector3int16")
|
|
519
|
+
|
|
520
|
+
--[[**
|
|
521
|
+
ensures value is any of the given literal values
|
|
522
|
+
|
|
523
|
+
@param literals The literals to check against
|
|
524
|
+
|
|
525
|
+
@returns A function that will return true if the condition is passed
|
|
526
|
+
**--]]
|
|
527
|
+
function t.literalList(literals)
|
|
528
|
+
-- optimization for primitive types
|
|
529
|
+
local set = {}
|
|
530
|
+
for _, literal in ipairs(literals) do
|
|
531
|
+
set[literal] = true
|
|
532
|
+
end
|
|
533
|
+
return function(value)
|
|
534
|
+
if set[value] then
|
|
535
|
+
return true
|
|
536
|
+
end
|
|
537
|
+
for _, literal in ipairs(literals) do
|
|
538
|
+
if literal == value then
|
|
539
|
+
return true
|
|
540
|
+
end
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
return false, "bad type for literal list"
|
|
544
|
+
end
|
|
545
|
+
end
|
|
546
|
+
|
|
547
|
+
--[[**
|
|
548
|
+
ensures value is a given literal value
|
|
549
|
+
|
|
550
|
+
@param literal The literal to use
|
|
551
|
+
|
|
552
|
+
@returns A function that will return true iff the condition is passed
|
|
553
|
+
**--]]
|
|
554
|
+
function t.literal(...)
|
|
555
|
+
local size = select("#", ...)
|
|
556
|
+
if size == 1 then
|
|
557
|
+
local literal = ...
|
|
558
|
+
return function(value)
|
|
559
|
+
if value ~= literal then
|
|
560
|
+
return false, string.format("expected %s, got %s", tostring(literal), tostring(value))
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
return true
|
|
564
|
+
end
|
|
565
|
+
else
|
|
566
|
+
local literals = {}
|
|
567
|
+
for i = 1, size do
|
|
568
|
+
local value = select(i, ...)
|
|
569
|
+
literals[i] = t.literal(value)
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
return t.unionList(literals)
|
|
573
|
+
end
|
|
574
|
+
end
|
|
575
|
+
|
|
576
|
+
--[[**
|
|
577
|
+
DEPRECATED
|
|
578
|
+
Please use t.literal
|
|
579
|
+
**--]]
|
|
580
|
+
t.exactly = t.literal
|
|
581
|
+
|
|
582
|
+
--[[**
|
|
583
|
+
Returns a t.union of each key in the table as a t.literal
|
|
584
|
+
|
|
585
|
+
@param keyTable The table to get keys from
|
|
586
|
+
|
|
587
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
588
|
+
**--]]
|
|
589
|
+
function t.keyOf(keyTable)
|
|
590
|
+
local keys = {}
|
|
591
|
+
local length = 0
|
|
592
|
+
for key in pairs(keyTable) do
|
|
593
|
+
length = length + 1
|
|
594
|
+
keys[length] = key
|
|
595
|
+
end
|
|
596
|
+
|
|
597
|
+
return t.literal(table.unpack(keys, 1, length))
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
--[[**
|
|
601
|
+
Returns a t.union of each value in the table as a t.literal
|
|
602
|
+
|
|
603
|
+
@param valueTable The table to get values from
|
|
604
|
+
|
|
605
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
606
|
+
**--]]
|
|
607
|
+
function t.valueOf(valueTable)
|
|
608
|
+
local values = {}
|
|
609
|
+
local length = 0
|
|
610
|
+
for _, value in pairs(valueTable) do
|
|
611
|
+
length = length + 1
|
|
612
|
+
values[length] = value
|
|
613
|
+
end
|
|
614
|
+
|
|
615
|
+
return t.literal(table.unpack(values, 1, length))
|
|
616
|
+
end
|
|
617
|
+
|
|
618
|
+
--[[**
|
|
619
|
+
ensures value is an integer
|
|
620
|
+
|
|
621
|
+
@param value The value to check against
|
|
622
|
+
|
|
623
|
+
@returns True iff the condition is satisfied, false otherwise
|
|
624
|
+
**--]]
|
|
625
|
+
function t.integer(value)
|
|
626
|
+
local success, errMsg = t.number(value)
|
|
627
|
+
if not success then
|
|
628
|
+
return false, errMsg or ""
|
|
629
|
+
end
|
|
630
|
+
|
|
631
|
+
if value % 1 == 0 then
|
|
632
|
+
return true
|
|
633
|
+
else
|
|
634
|
+
return false, string.format("integer expected, got %s", value)
|
|
635
|
+
end
|
|
636
|
+
end
|
|
637
|
+
|
|
638
|
+
--[[**
|
|
639
|
+
ensures value is a number where min <= value
|
|
640
|
+
|
|
641
|
+
@param min The minimum to use
|
|
642
|
+
|
|
643
|
+
@returns A function that will return true iff the condition is passed
|
|
644
|
+
**--]]
|
|
645
|
+
function t.numberMin(min)
|
|
646
|
+
return function(value)
|
|
647
|
+
local success, errMsg = t.number(value)
|
|
648
|
+
if not success then
|
|
649
|
+
return false, errMsg or ""
|
|
650
|
+
end
|
|
651
|
+
|
|
652
|
+
if value >= min then
|
|
653
|
+
return true
|
|
654
|
+
else
|
|
655
|
+
return false, string.format("number >= %s expected, got %s", min, value)
|
|
656
|
+
end
|
|
657
|
+
end
|
|
658
|
+
end
|
|
659
|
+
|
|
660
|
+
--[[**
|
|
661
|
+
ensures value is a number where value <= max
|
|
662
|
+
|
|
663
|
+
@param max The maximum to use
|
|
664
|
+
|
|
665
|
+
@returns A function that will return true iff the condition is passed
|
|
666
|
+
**--]]
|
|
667
|
+
function t.numberMax(max)
|
|
668
|
+
return function(value)
|
|
669
|
+
local success, errMsg = t.number(value)
|
|
670
|
+
if not success then
|
|
671
|
+
return false, errMsg
|
|
672
|
+
end
|
|
673
|
+
|
|
674
|
+
if value <= max then
|
|
675
|
+
return true
|
|
676
|
+
else
|
|
677
|
+
return false, string.format("number <= %s expected, got %s", max, value)
|
|
678
|
+
end
|
|
679
|
+
end
|
|
680
|
+
end
|
|
681
|
+
|
|
682
|
+
--[[**
|
|
683
|
+
ensures value is a number where min < value
|
|
684
|
+
|
|
685
|
+
@param min The minimum to use
|
|
686
|
+
|
|
687
|
+
@returns A function that will return true iff the condition is passed
|
|
688
|
+
**--]]
|
|
689
|
+
function t.numberMinExclusive(min)
|
|
690
|
+
return function(value)
|
|
691
|
+
local success, errMsg = t.number(value)
|
|
692
|
+
if not success then
|
|
693
|
+
return false, errMsg or ""
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
if min < value then
|
|
697
|
+
return true
|
|
698
|
+
else
|
|
699
|
+
return false, string.format("number > %s expected, got %s", min, value)
|
|
700
|
+
end
|
|
701
|
+
end
|
|
702
|
+
end
|
|
703
|
+
|
|
704
|
+
--[[**
|
|
705
|
+
ensures value is a number where value < max
|
|
706
|
+
|
|
707
|
+
@param max The maximum to use
|
|
708
|
+
|
|
709
|
+
@returns A function that will return true iff the condition is passed
|
|
710
|
+
**--]]
|
|
711
|
+
function t.numberMaxExclusive(max)
|
|
712
|
+
return function(value)
|
|
713
|
+
local success, errMsg = t.number(value)
|
|
714
|
+
if not success then
|
|
715
|
+
return false, errMsg or ""
|
|
716
|
+
end
|
|
717
|
+
|
|
718
|
+
if value < max then
|
|
719
|
+
return true
|
|
720
|
+
else
|
|
721
|
+
return false, string.format("number < %s expected, got %s", max, value)
|
|
722
|
+
end
|
|
723
|
+
end
|
|
724
|
+
end
|
|
725
|
+
|
|
726
|
+
--[[**
|
|
727
|
+
ensures value is a number where value > 0
|
|
728
|
+
|
|
729
|
+
@returns A function that will return true iff the condition is passed
|
|
730
|
+
**--]]
|
|
731
|
+
t.numberPositive = t.numberMinExclusive(0)
|
|
732
|
+
|
|
733
|
+
--[[**
|
|
734
|
+
ensures value is a number where value < 0
|
|
735
|
+
|
|
736
|
+
@returns A function that will return true iff the condition is passed
|
|
737
|
+
**--]]
|
|
738
|
+
t.numberNegative = t.numberMaxExclusive(0)
|
|
739
|
+
|
|
740
|
+
--[[**
|
|
741
|
+
ensures value is a number where min <= value <= max
|
|
742
|
+
|
|
743
|
+
@param min The minimum to use
|
|
744
|
+
@param max The maximum to use
|
|
745
|
+
|
|
746
|
+
@returns A function that will return true iff the condition is passed
|
|
747
|
+
**--]]
|
|
748
|
+
function t.numberConstrained(min, max)
|
|
749
|
+
assert(t.number(min))
|
|
750
|
+
assert(t.number(max))
|
|
751
|
+
local minCheck = t.numberMin(min)
|
|
752
|
+
local maxCheck = t.numberMax(max)
|
|
753
|
+
|
|
754
|
+
return function(value)
|
|
755
|
+
local minSuccess, minErrMsg = minCheck(value)
|
|
756
|
+
if not minSuccess then
|
|
757
|
+
return false, minErrMsg or ""
|
|
758
|
+
end
|
|
759
|
+
|
|
760
|
+
local maxSuccess, maxErrMsg = maxCheck(value)
|
|
761
|
+
if not maxSuccess then
|
|
762
|
+
return false, maxErrMsg or ""
|
|
763
|
+
end
|
|
764
|
+
|
|
765
|
+
return true
|
|
766
|
+
end
|
|
767
|
+
end
|
|
768
|
+
|
|
769
|
+
--[[**
|
|
770
|
+
ensures value is a number where min < value < max
|
|
771
|
+
|
|
772
|
+
@param min The minimum to use
|
|
773
|
+
@param max The maximum to use
|
|
774
|
+
|
|
775
|
+
@returns A function that will return true iff the condition is passed
|
|
776
|
+
**--]]
|
|
777
|
+
function t.numberConstrainedExclusive(min, max)
|
|
778
|
+
assert(t.number(min))
|
|
779
|
+
assert(t.number(max))
|
|
780
|
+
local minCheck = t.numberMinExclusive(min)
|
|
781
|
+
local maxCheck = t.numberMaxExclusive(max)
|
|
782
|
+
|
|
783
|
+
return function(value)
|
|
784
|
+
local minSuccess, minErrMsg = minCheck(value)
|
|
785
|
+
if not minSuccess then
|
|
786
|
+
return false, minErrMsg or ""
|
|
787
|
+
end
|
|
788
|
+
|
|
789
|
+
local maxSuccess, maxErrMsg = maxCheck(value)
|
|
790
|
+
if not maxSuccess then
|
|
791
|
+
return false, maxErrMsg or ""
|
|
792
|
+
end
|
|
793
|
+
|
|
794
|
+
return true
|
|
795
|
+
end
|
|
796
|
+
end
|
|
797
|
+
|
|
798
|
+
--[[**
|
|
799
|
+
ensures value matches string pattern
|
|
800
|
+
|
|
801
|
+
@param string pattern to check against
|
|
802
|
+
|
|
803
|
+
@returns A function that will return true iff the condition is passed
|
|
804
|
+
**--]]
|
|
805
|
+
function t.match(pattern)
|
|
806
|
+
assert(t.string(pattern))
|
|
807
|
+
return function(value)
|
|
808
|
+
local stringSuccess, stringErrMsg = t.string(value)
|
|
809
|
+
if not stringSuccess then
|
|
810
|
+
return false, stringErrMsg
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
if string.match(value, pattern) == nil then
|
|
814
|
+
return false, string.format("%q failed to match pattern %q", value, pattern)
|
|
815
|
+
end
|
|
816
|
+
|
|
817
|
+
return true
|
|
818
|
+
end
|
|
819
|
+
end
|
|
820
|
+
|
|
821
|
+
--[[**
|
|
822
|
+
ensures value is either nil or passes check
|
|
823
|
+
|
|
824
|
+
@param check The check to use
|
|
825
|
+
|
|
826
|
+
@returns A function that will return true iff the condition is passed
|
|
827
|
+
**--]]
|
|
828
|
+
function t.optional(check)
|
|
829
|
+
assert(t.callback(check))
|
|
830
|
+
return function(value)
|
|
831
|
+
if value == nil then
|
|
832
|
+
return true
|
|
833
|
+
end
|
|
834
|
+
|
|
835
|
+
local success, errMsg = check(value)
|
|
836
|
+
if success then
|
|
837
|
+
return true
|
|
838
|
+
else
|
|
839
|
+
return false, string.format("(optional) %s", errMsg or "")
|
|
840
|
+
end
|
|
841
|
+
end
|
|
842
|
+
end
|
|
843
|
+
|
|
844
|
+
--[[**
|
|
845
|
+
matches given tuple against tuple type definition
|
|
846
|
+
|
|
847
|
+
@param ... The type definition for the tuples
|
|
848
|
+
|
|
849
|
+
@returns A function that will return true iff the condition is passed
|
|
850
|
+
**--]]
|
|
851
|
+
function t.tuple(...)
|
|
852
|
+
local checks = { ... }
|
|
853
|
+
return function(...)
|
|
854
|
+
local args = { ... }
|
|
855
|
+
for i, check in ipairs(checks) do
|
|
856
|
+
local success, errMsg = check(args[i])
|
|
857
|
+
if success == false then
|
|
858
|
+
return false, string.format("Bad tuple index #%s:\n\t%s", i, errMsg or "")
|
|
859
|
+
end
|
|
860
|
+
end
|
|
861
|
+
|
|
862
|
+
return true
|
|
863
|
+
end
|
|
864
|
+
end
|
|
865
|
+
|
|
866
|
+
--[[**
|
|
867
|
+
ensures all keys in given table pass check
|
|
868
|
+
|
|
869
|
+
@param check The function to use to check the keys
|
|
870
|
+
|
|
871
|
+
@returns A function that will return true iff the condition is passed
|
|
872
|
+
**--]]
|
|
873
|
+
function t.keys(check)
|
|
874
|
+
assert(t.callback(check))
|
|
875
|
+
return function(value)
|
|
876
|
+
local tableSuccess, tableErrMsg = t.table(value)
|
|
877
|
+
if tableSuccess == false then
|
|
878
|
+
return false, tableErrMsg or ""
|
|
879
|
+
end
|
|
880
|
+
|
|
881
|
+
for key in pairs(value) do
|
|
882
|
+
local success, errMsg = check(key)
|
|
883
|
+
if success == false then
|
|
884
|
+
return false, string.format("bad key %s:\n\t%s", tostring(key), errMsg or "")
|
|
885
|
+
end
|
|
886
|
+
end
|
|
887
|
+
|
|
888
|
+
return true
|
|
889
|
+
end
|
|
890
|
+
end
|
|
891
|
+
|
|
892
|
+
--[[**
|
|
893
|
+
ensures all values in given table pass check
|
|
894
|
+
|
|
895
|
+
@param check The function to use to check the values
|
|
896
|
+
|
|
897
|
+
@returns A function that will return true iff the condition is passed
|
|
898
|
+
**--]]
|
|
899
|
+
function t.values(check)
|
|
900
|
+
assert(t.callback(check))
|
|
901
|
+
return function(value)
|
|
902
|
+
local tableSuccess, tableErrMsg = t.table(value)
|
|
903
|
+
if tableSuccess == false then
|
|
904
|
+
return false, tableErrMsg or ""
|
|
905
|
+
end
|
|
906
|
+
|
|
907
|
+
for key, val in pairs(value) do
|
|
908
|
+
local success, errMsg = check(val)
|
|
909
|
+
if success == false then
|
|
910
|
+
return false, string.format("bad value for key %s:\n\t%s", tostring(key), errMsg or "")
|
|
911
|
+
end
|
|
912
|
+
end
|
|
913
|
+
|
|
914
|
+
return true
|
|
915
|
+
end
|
|
916
|
+
end
|
|
917
|
+
|
|
918
|
+
--[[**
|
|
919
|
+
ensures value is a table and all keys pass keyCheck and all values pass valueCheck
|
|
920
|
+
|
|
921
|
+
@param keyCheck The function to use to check the keys
|
|
922
|
+
@param valueCheck The function to use to check the values
|
|
923
|
+
|
|
924
|
+
@returns A function that will return true iff the condition is passed
|
|
925
|
+
**--]]
|
|
926
|
+
function t.map(keyCheck, valueCheck)
|
|
927
|
+
assert(t.callback(keyCheck))
|
|
928
|
+
assert(t.callback(valueCheck))
|
|
929
|
+
local keyChecker = t.keys(keyCheck)
|
|
930
|
+
local valueChecker = t.values(valueCheck)
|
|
931
|
+
|
|
932
|
+
return function(value)
|
|
933
|
+
local keySuccess, keyErr = keyChecker(value)
|
|
934
|
+
if not keySuccess then
|
|
935
|
+
return false, keyErr or ""
|
|
936
|
+
end
|
|
937
|
+
|
|
938
|
+
local valueSuccess, valueErr = valueChecker(value)
|
|
939
|
+
if not valueSuccess then
|
|
940
|
+
return false, valueErr or ""
|
|
941
|
+
end
|
|
942
|
+
|
|
943
|
+
return true
|
|
944
|
+
end
|
|
945
|
+
end
|
|
946
|
+
|
|
947
|
+
--[[**
|
|
948
|
+
ensures value is a table and all keys pass valueCheck and all values are true
|
|
949
|
+
|
|
950
|
+
@param valueCheck The function to use to check the values
|
|
951
|
+
|
|
952
|
+
@returns A function that will return true iff the condition is passed
|
|
953
|
+
**--]]
|
|
954
|
+
function t.set(valueCheck)
|
|
955
|
+
return t.map(valueCheck, t.literal(true))
|
|
956
|
+
end
|
|
957
|
+
|
|
958
|
+
do
|
|
959
|
+
local arrayKeysCheck = t.keys(t.integer)
|
|
960
|
+
--[[**
|
|
961
|
+
ensures value is an array and all values of the array match check
|
|
962
|
+
|
|
963
|
+
@param check The check to compare all values with
|
|
964
|
+
|
|
965
|
+
@returns A function that will return true iff the condition is passed
|
|
966
|
+
**--]]
|
|
967
|
+
function t.array(check)
|
|
968
|
+
assert(t.callback(check))
|
|
969
|
+
local valuesCheck = t.values(check)
|
|
970
|
+
|
|
971
|
+
return function(value)
|
|
972
|
+
local keySuccess, keyErrMsg = arrayKeysCheck(value)
|
|
973
|
+
if keySuccess == false then
|
|
974
|
+
return false, string.format("[array] %s", keyErrMsg or "")
|
|
975
|
+
end
|
|
976
|
+
|
|
977
|
+
-- # is unreliable for sparse arrays
|
|
978
|
+
-- Count upwards using ipairs to avoid false positives from the behavior of #
|
|
979
|
+
local arraySize = 0
|
|
980
|
+
|
|
981
|
+
for _ in ipairs(value) do
|
|
982
|
+
arraySize = arraySize + 1
|
|
983
|
+
end
|
|
984
|
+
|
|
985
|
+
for key in pairs(value) do
|
|
986
|
+
if key < 1 or key > arraySize then
|
|
987
|
+
return false, string.format("[array] key %s must be sequential", tostring(key))
|
|
988
|
+
end
|
|
989
|
+
end
|
|
990
|
+
|
|
991
|
+
local valueSuccess, valueErrMsg = valuesCheck(value)
|
|
992
|
+
if not valueSuccess then
|
|
993
|
+
return false, string.format("[array] %s", valueErrMsg or "")
|
|
994
|
+
end
|
|
995
|
+
|
|
996
|
+
return true
|
|
997
|
+
end
|
|
998
|
+
end
|
|
999
|
+
|
|
1000
|
+
--[[**
|
|
1001
|
+
ensures value is an array of a strict makeup and size
|
|
1002
|
+
|
|
1003
|
+
@param check The check to compare all values with
|
|
1004
|
+
|
|
1005
|
+
@returns A function that will return true iff the condition is passed
|
|
1006
|
+
**--]]
|
|
1007
|
+
function t.strictArray(...)
|
|
1008
|
+
local valueTypes = { ... }
|
|
1009
|
+
assert(t.array(t.callback)(valueTypes))
|
|
1010
|
+
|
|
1011
|
+
return function(value)
|
|
1012
|
+
local keySuccess, keyErrMsg = arrayKeysCheck(value)
|
|
1013
|
+
if keySuccess == false then
|
|
1014
|
+
return false, string.format("[strictArray] %s", keyErrMsg or "")
|
|
1015
|
+
end
|
|
1016
|
+
|
|
1017
|
+
-- If there's more than the set array size, disallow
|
|
1018
|
+
if #valueTypes < #value then
|
|
1019
|
+
return false, string.format("[strictArray] Array size exceeds limit of %d", #valueTypes)
|
|
1020
|
+
end
|
|
1021
|
+
|
|
1022
|
+
for idx, typeFn in pairs(valueTypes) do
|
|
1023
|
+
local typeSuccess, typeErrMsg = typeFn(value[idx])
|
|
1024
|
+
if not typeSuccess then
|
|
1025
|
+
return false, string.format("[strictArray] Array index #%d - %s", idx, typeErrMsg)
|
|
1026
|
+
end
|
|
1027
|
+
end
|
|
1028
|
+
|
|
1029
|
+
return true
|
|
1030
|
+
end
|
|
1031
|
+
end
|
|
1032
|
+
end
|
|
1033
|
+
|
|
1034
|
+
do
|
|
1035
|
+
local callbackArray = t.array(t.callback)
|
|
1036
|
+
--[[**
|
|
1037
|
+
creates a union type
|
|
1038
|
+
|
|
1039
|
+
@param checks The checks to union
|
|
1040
|
+
|
|
1041
|
+
@returns A function that will return true iff the condition is passed
|
|
1042
|
+
**--]]
|
|
1043
|
+
function t.unionList(checks)
|
|
1044
|
+
assert(callbackArray(checks))
|
|
1045
|
+
|
|
1046
|
+
return function(value)
|
|
1047
|
+
for _, check in ipairs(checks) do
|
|
1048
|
+
if check(value) then
|
|
1049
|
+
return true
|
|
1050
|
+
end
|
|
1051
|
+
end
|
|
1052
|
+
|
|
1053
|
+
return false, "bad type for union"
|
|
1054
|
+
end
|
|
1055
|
+
end
|
|
1056
|
+
|
|
1057
|
+
--[[**
|
|
1058
|
+
creates a union type
|
|
1059
|
+
|
|
1060
|
+
@param ... The checks to union
|
|
1061
|
+
|
|
1062
|
+
@returns A function that will return true iff the condition is passed
|
|
1063
|
+
**--]]
|
|
1064
|
+
function t.union(...)
|
|
1065
|
+
return t.unionList({ ... })
|
|
1066
|
+
end
|
|
1067
|
+
|
|
1068
|
+
--[[**
|
|
1069
|
+
Alias for t.union
|
|
1070
|
+
**--]]
|
|
1071
|
+
t.some = t.union
|
|
1072
|
+
|
|
1073
|
+
--[[**
|
|
1074
|
+
creates an intersection type
|
|
1075
|
+
|
|
1076
|
+
@param checks The checks to intersect
|
|
1077
|
+
|
|
1078
|
+
@returns A function that will return true iff the condition is passed
|
|
1079
|
+
**--]]
|
|
1080
|
+
function t.intersectionList(checks)
|
|
1081
|
+
assert(callbackArray(checks))
|
|
1082
|
+
|
|
1083
|
+
return function(value)
|
|
1084
|
+
for _, check in ipairs(checks) do
|
|
1085
|
+
local success, errMsg = check(value)
|
|
1086
|
+
if not success then
|
|
1087
|
+
return false, errMsg or ""
|
|
1088
|
+
end
|
|
1089
|
+
end
|
|
1090
|
+
|
|
1091
|
+
return true
|
|
1092
|
+
end
|
|
1093
|
+
end
|
|
1094
|
+
|
|
1095
|
+
--[[**
|
|
1096
|
+
creates an intersection type
|
|
1097
|
+
|
|
1098
|
+
@param ... The checks to intersect
|
|
1099
|
+
|
|
1100
|
+
@returns A function that will return true iff the condition is passed
|
|
1101
|
+
**--]]
|
|
1102
|
+
function t.intersection(...)
|
|
1103
|
+
return t.intersectionList({ ... })
|
|
1104
|
+
end
|
|
1105
|
+
|
|
1106
|
+
--[[**
|
|
1107
|
+
Alias for t.intersection
|
|
1108
|
+
**--]]
|
|
1109
|
+
t.every = t.intersection
|
|
1110
|
+
end
|
|
1111
|
+
|
|
1112
|
+
do
|
|
1113
|
+
local checkInterface = t.map(t.any, t.callback)
|
|
1114
|
+
--[[**
|
|
1115
|
+
ensures value matches given interface definition
|
|
1116
|
+
|
|
1117
|
+
@param checkTable The interface definition
|
|
1118
|
+
|
|
1119
|
+
@returns A function that will return true iff the condition is passed
|
|
1120
|
+
**--]]
|
|
1121
|
+
function t.interface(checkTable)
|
|
1122
|
+
assert(checkInterface(checkTable))
|
|
1123
|
+
return function(value)
|
|
1124
|
+
local tableSuccess, tableErrMsg = t.table(value)
|
|
1125
|
+
if tableSuccess == false then
|
|
1126
|
+
return false, tableErrMsg or ""
|
|
1127
|
+
end
|
|
1128
|
+
|
|
1129
|
+
for key, check in pairs(checkTable) do
|
|
1130
|
+
local success, errMsg = check(value[key])
|
|
1131
|
+
if success == false then
|
|
1132
|
+
return false, string.format("[interface] bad value for %s:\n\t%s", tostring(key), errMsg or "")
|
|
1133
|
+
end
|
|
1134
|
+
end
|
|
1135
|
+
|
|
1136
|
+
return true
|
|
1137
|
+
end
|
|
1138
|
+
end
|
|
1139
|
+
|
|
1140
|
+
--[[**
|
|
1141
|
+
ensures value matches given interface definition strictly
|
|
1142
|
+
|
|
1143
|
+
@param checkTable The interface definition
|
|
1144
|
+
|
|
1145
|
+
@returns A function that will return true iff the condition is passed
|
|
1146
|
+
**--]]
|
|
1147
|
+
function t.strictInterface(checkTable)
|
|
1148
|
+
assert(checkInterface(checkTable))
|
|
1149
|
+
return function(value)
|
|
1150
|
+
local tableSuccess, tableErrMsg = t.table(value)
|
|
1151
|
+
if tableSuccess == false then
|
|
1152
|
+
return false, tableErrMsg or ""
|
|
1153
|
+
end
|
|
1154
|
+
|
|
1155
|
+
for key, check in pairs(checkTable) do
|
|
1156
|
+
local success, errMsg = check(value[key])
|
|
1157
|
+
if success == false then
|
|
1158
|
+
return false, string.format("[interface] bad value for %s:\n\t%s", tostring(key), errMsg or "")
|
|
1159
|
+
end
|
|
1160
|
+
end
|
|
1161
|
+
|
|
1162
|
+
for key in pairs(value) do
|
|
1163
|
+
if not checkTable[key] then
|
|
1164
|
+
return false, string.format("[interface] unexpected field %q", tostring(key))
|
|
1165
|
+
end
|
|
1166
|
+
end
|
|
1167
|
+
|
|
1168
|
+
return true
|
|
1169
|
+
end
|
|
1170
|
+
end
|
|
1171
|
+
end
|
|
1172
|
+
|
|
1173
|
+
--[[**
|
|
1174
|
+
ensure value is an Instance and it's ClassName matches the given ClassName
|
|
1175
|
+
|
|
1176
|
+
@param className The class name to check for
|
|
1177
|
+
|
|
1178
|
+
@returns A function that will return true iff the condition is passed
|
|
1179
|
+
**--]]
|
|
1180
|
+
function t.instanceOf(className, childTable)
|
|
1181
|
+
assert(t.string(className))
|
|
1182
|
+
|
|
1183
|
+
local childrenCheck
|
|
1184
|
+
if childTable ~= nil then
|
|
1185
|
+
childrenCheck = t.children(childTable)
|
|
1186
|
+
end
|
|
1187
|
+
|
|
1188
|
+
return function(value)
|
|
1189
|
+
local instanceSuccess, instanceErrMsg = t.Instance(value)
|
|
1190
|
+
if not instanceSuccess then
|
|
1191
|
+
return false, instanceErrMsg or ""
|
|
1192
|
+
end
|
|
1193
|
+
|
|
1194
|
+
if value.ClassName ~= className then
|
|
1195
|
+
return false, string.format("%s expected, got %s", className, value.ClassName)
|
|
1196
|
+
end
|
|
1197
|
+
|
|
1198
|
+
if childrenCheck then
|
|
1199
|
+
local childrenSuccess, childrenErrMsg = childrenCheck(value)
|
|
1200
|
+
if not childrenSuccess then
|
|
1201
|
+
return false, childrenErrMsg
|
|
1202
|
+
end
|
|
1203
|
+
end
|
|
1204
|
+
|
|
1205
|
+
return true
|
|
1206
|
+
end
|
|
1207
|
+
end
|
|
1208
|
+
|
|
1209
|
+
t.instance = t.instanceOf
|
|
1210
|
+
|
|
1211
|
+
--[[**
|
|
1212
|
+
ensure value is an Instance and it's ClassName matches the given ClassName by an IsA comparison
|
|
1213
|
+
|
|
1214
|
+
@param className The class name to check for
|
|
1215
|
+
|
|
1216
|
+
@returns A function that will return true iff the condition is passed
|
|
1217
|
+
**--]]
|
|
1218
|
+
function t.instanceIsA(className, childTable)
|
|
1219
|
+
assert(t.string(className))
|
|
1220
|
+
|
|
1221
|
+
local childrenCheck
|
|
1222
|
+
if childTable ~= nil then
|
|
1223
|
+
childrenCheck = t.children(childTable)
|
|
1224
|
+
end
|
|
1225
|
+
|
|
1226
|
+
return function(value)
|
|
1227
|
+
local instanceSuccess, instanceErrMsg = t.Instance(value)
|
|
1228
|
+
if not instanceSuccess then
|
|
1229
|
+
return false, instanceErrMsg or ""
|
|
1230
|
+
end
|
|
1231
|
+
|
|
1232
|
+
if not value:IsA(className) then
|
|
1233
|
+
return false, string.format("%s expected, got %s", className, value.ClassName)
|
|
1234
|
+
end
|
|
1235
|
+
|
|
1236
|
+
if childrenCheck then
|
|
1237
|
+
local childrenSuccess, childrenErrMsg = childrenCheck(value)
|
|
1238
|
+
if not childrenSuccess then
|
|
1239
|
+
return false, childrenErrMsg
|
|
1240
|
+
end
|
|
1241
|
+
end
|
|
1242
|
+
|
|
1243
|
+
return true
|
|
1244
|
+
end
|
|
1245
|
+
end
|
|
1246
|
+
|
|
1247
|
+
--[[**
|
|
1248
|
+
ensures value is an enum of the correct type
|
|
1249
|
+
|
|
1250
|
+
@param enum The enum to check
|
|
1251
|
+
|
|
1252
|
+
@returns A function that will return true iff the condition is passed
|
|
1253
|
+
**--]]
|
|
1254
|
+
function t.enum(enum)
|
|
1255
|
+
assert(t.Enum(enum))
|
|
1256
|
+
return function(value)
|
|
1257
|
+
local enumItemSuccess, enumItemErrMsg = t.EnumItem(value)
|
|
1258
|
+
if not enumItemSuccess then
|
|
1259
|
+
return false, enumItemErrMsg
|
|
1260
|
+
end
|
|
1261
|
+
|
|
1262
|
+
if value.EnumType == enum then
|
|
1263
|
+
return true
|
|
1264
|
+
else
|
|
1265
|
+
return false, string.format("enum of %s expected, got enum of %s", tostring(enum), tostring(value.EnumType))
|
|
1266
|
+
end
|
|
1267
|
+
end
|
|
1268
|
+
end
|
|
1269
|
+
|
|
1270
|
+
do
|
|
1271
|
+
local checkWrap = t.tuple(t.callback, t.callback)
|
|
1272
|
+
|
|
1273
|
+
--[[**
|
|
1274
|
+
wraps a callback in an assert with checkArgs
|
|
1275
|
+
|
|
1276
|
+
@param callback The function to wrap
|
|
1277
|
+
@param checkArgs The function to use to check arguments in the assert
|
|
1278
|
+
|
|
1279
|
+
@returns A function that first asserts using checkArgs and then calls callback
|
|
1280
|
+
**--]]
|
|
1281
|
+
function t.wrap(callback, checkArgs)
|
|
1282
|
+
assert(checkWrap(callback, checkArgs))
|
|
1283
|
+
return function(...)
|
|
1284
|
+
assert(checkArgs(...))
|
|
1285
|
+
return callback(...)
|
|
1286
|
+
end
|
|
1287
|
+
end
|
|
1288
|
+
end
|
|
1289
|
+
|
|
1290
|
+
--[[**
|
|
1291
|
+
asserts a given check
|
|
1292
|
+
|
|
1293
|
+
@param check The function to wrap with an assert
|
|
1294
|
+
|
|
1295
|
+
@returns A function that simply wraps the given check in an assert
|
|
1296
|
+
**--]]
|
|
1297
|
+
function t.strict(check)
|
|
1298
|
+
return function(...)
|
|
1299
|
+
assert(check(...))
|
|
1300
|
+
end
|
|
1301
|
+
end
|
|
1302
|
+
|
|
1303
|
+
do
|
|
1304
|
+
local checkChildren = t.map(t.string, t.callback)
|
|
1305
|
+
|
|
1306
|
+
--[[**
|
|
1307
|
+
Takes a table where keys are child names and values are functions to check the children against.
|
|
1308
|
+
Pass an instance tree into the function.
|
|
1309
|
+
If at least one child passes each check, the overall check passes.
|
|
1310
|
+
|
|
1311
|
+
Warning! If you pass in a tree with more than one child of the same name, this function will always return false
|
|
1312
|
+
|
|
1313
|
+
@param checkTable The table to check against
|
|
1314
|
+
|
|
1315
|
+
@returns A function that checks an instance tree
|
|
1316
|
+
**--]]
|
|
1317
|
+
function t.children(checkTable)
|
|
1318
|
+
assert(checkChildren(checkTable))
|
|
1319
|
+
|
|
1320
|
+
return function(value)
|
|
1321
|
+
local instanceSuccess, instanceErrMsg = t.Instance(value)
|
|
1322
|
+
if not instanceSuccess then
|
|
1323
|
+
return false, instanceErrMsg or ""
|
|
1324
|
+
end
|
|
1325
|
+
|
|
1326
|
+
local childrenByName = {}
|
|
1327
|
+
for _, child in ipairs(value:GetChildren()) do
|
|
1328
|
+
local name = child.Name
|
|
1329
|
+
if checkTable[name] then
|
|
1330
|
+
if childrenByName[name] then
|
|
1331
|
+
return false, string.format("Cannot process multiple children with the same name %q", name)
|
|
1332
|
+
end
|
|
1333
|
+
|
|
1334
|
+
childrenByName[name] = child
|
|
1335
|
+
end
|
|
1336
|
+
end
|
|
1337
|
+
|
|
1338
|
+
for name, check in pairs(checkTable) do
|
|
1339
|
+
local success, errMsg = check(childrenByName[name])
|
|
1340
|
+
if not success then
|
|
1341
|
+
return false, string.format("[%s.%s] %s", value:GetFullName(), name, errMsg or "")
|
|
1342
|
+
end
|
|
1343
|
+
end
|
|
1344
|
+
|
|
1345
|
+
return true
|
|
1346
|
+
end
|
|
1347
|
+
end
|
|
1348
|
+
end
|
|
1349
|
+
|
|
1350
|
+
return t
|