-
Notifications
You must be signed in to change notification settings - Fork 0
/
Interface.lua
89 lines (73 loc) · 2.03 KB
/
Interface.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
-- simple interface implementation
local Interface = {}
Interface.__index = Interface
Interface.__type = "Interface"
local Errors = {
[0] = function(...) return error(("Expected interface value for property '%s'"):format(...)) end,
[1] = function(...) return error(("Unknown property '%s'"):format(...)) end,
[2] = function(...) return error(("Expected property '%s' to be of type '%s'. Got '%s' instead"):format(...)) end,
[3] = function(...) return error(("Missing property '%s'"):format(...)) end
}
-- static methods
function Interface:Value(dataType, optional)
return setmetatable({
DataType = dataType,
Optional = optional or false,
}, {
__index = function(t, k)
if k == "type" then
return "InterfaceValue"
end
end,
})
end
-- object methods
function Interface:Create(t)
local optionals = {}
local requireds = {}
for name, interfaceValue in pairs(t) do
if not (interfaceValue.type == "InterfaceValue") then
Errors[0](name)
end
if interfaceValue.Optional then
optionals[name] = interfaceValue
else
requireds[name] = interfaceValue
end
end
return setmetatable({
Props = t,
Requireds = requireds,
Optionals = optionals
}, Interface)
end
function Interface:GetRequireds()
return self.Requireds
end
function Interface:GetOptionals()
return self.Optionals
end
function Interface:Compare(supposedInterface, strict)
local alike = true
for name, value in pairs(supposedInterface) do
if not self.Props[name] then
alike = false
if strict then Errors[1](name) end
end
if not (typeof(value) == self.Props[name].DataType) then
alike = false
if strict then Errors[2](name, self.Props[name].DataType, typeof(value)) end
end
end
for name, interfaceValue in pairs(self:GetRequireds()) do
if not supposedInterface[name] then
alike = false
if strict then Errors[3](name) end
end
end
return alike
end
function Interface:Implement(supposedInterface)
return self:Compare(supposedInterface, true) and supposedInterface
end
return Interface