Skip to content

Instantly share code, notes, and snippets.

@gaymeowing
Created November 29, 2024 21:40
Show Gist options
  • Save gaymeowing/c1ee28e61be244c00e74f7161d764afb to your computer and use it in GitHub Desktop.
Save gaymeowing/c1ee28e61be244c00e74f7161d764afb to your computer and use it in GitHub Desktop.
a weak table utility so its easier to get types with weak tables
--!native
-- weak
-- a weak table utility so its easier to get types with weak tables
--[[
this has string temporarially, so that the type checker wont scream when
the __call metamethod is used
--]]
export type WeakType =
| string
| "kvs"
| "ks"
| "vs"
| "kv"
| "k"
| "v"
local FREEZE = table.freeze
local WEAK_PAIR_SHRINKABLE = FREEZE({ __mode = "kvs" })
local WEAK_VALUE_SHRINKABLE = FREEZE({ __mode = "vs" })
local WEAK_KEY_SHRINKABLE = FREEZE({ __mode = "ks" })
local WEAK_PAIR = FREEZE({ __mode = "kv" })
local WEAK_VALUE = FREEZE({ __mode = "v" })
local WEAK_KEY = FREEZE({ __mode = "k" })
local function GET_WEAK_META_FOR_TYPE(type: WeakType): { __mode: string }
return if type == "kvs" then
WEAK_PAIR_SHRINKABLE
elseif type == "vs" then
WEAK_VALUE_SHRINKABLE
elseif type == "ks" then
WEAK_KEY_SHRINKABLE
elseif type == "kv" then
WEAK_PAIR
elseif type == "k" then
WEAK_KEY
else
WEAK_VALUE
end
local weak_mt = {}
--[[
Creates a new weak table of the provided type.
]]
function weak_mt.__call<S, T>(self: S, type: WeakType): T
return setmetatable({} :: any, GET_WEAK_META_FOR_TYPE(type))
end
local weak = setmetatable({}, FREEZE(weak_mt))
--[[
Sets the metatable of the provided table to the weak metatable
corrosponding to the provided type of weak table, and returns the provided table.
]]
function weak.weaken<T>(t: T & {}, type: WeakType): T
return setmetatable(t :: any, GET_WEAK_META_FOR_TYPE(type))
end
return FREEZE(weak)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment