mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-07-07 21:15:03 +00:00

Some checks failed
tinymist::ci / Duplicate Actions Detection (push) Has been cancelled
tinymist::ci / Check Clippy, Formatting, Completion, Documentation, and Tests (Linux) (push) Has been cancelled
tinymist::ci / Check Minimum Rust version and Tests (Windows) (push) Has been cancelled
tinymist::ci / prepare-build (push) Has been cancelled
tinymist::gh_pages / build-gh-pages (push) Has been cancelled
tinymist::ci / build-vsc-assets (push) Has been cancelled
tinymist::ci / build-vscode (push) Has been cancelled
tinymist::ci / build-vscode-others (push) Has been cancelled
tinymist::ci / publish-vscode (push) Has been cancelled
tinymist::ci / build-binary (push) Has been cancelled
tinymist::ci / E2E Tests (darwin-arm64 on macos-latest) (push) Has been cancelled
tinymist::ci / E2E Tests (linux-x64 on ubuntu-22.04) (push) Has been cancelled
tinymist::ci / E2E Tests (linux-x64 on ubuntu-latest) (push) Has been cancelled
tinymist::ci / E2E Tests (win32-x64 on windows-2019) (push) Has been cancelled
tinymist::ci / E2E Tests (win32-x64 on windows-latest) (push) Has been cancelled
* fix: bad link * feat(neovim): init lsp * feat(neovim): add bootstrap script * build: add notice
72 lines
2.1 KiB
Lua
72 lines
2.1 KiB
Lua
---@generic S
|
|
---@alias Constructor fun(self: any, ...: any): S
|
|
---@alias InductiveMethod fun(self: S, ...: any): any
|
|
|
|
---@alias ConstructorDefs table<string, Constructor> | table<string, table<string, InductiveMethod>>
|
|
|
|
---@class Inductive<S> : { [string]: InductiveMethod }
|
|
---@operator call(table): `S`
|
|
|
|
---Create a new inductive type.
|
|
---@param name string The name of the new type, used only for errors
|
|
---@param defs ConstructorDefs A table of constructor definitions
|
|
---@return Inductive
|
|
return function(name, defs)
|
|
local Type = {}
|
|
|
|
local to_obj
|
|
|
|
local _, first = next(defs)
|
|
if type(first) ~= 'table' then
|
|
to_obj = function(_, t)
|
|
return t
|
|
end
|
|
else
|
|
local methods = vim.tbl_keys(first)
|
|
|
|
to_obj = function(constructor_name, impl)
|
|
local obj = setmetatable({
|
|
serialize = function(self)
|
|
return { [constructor_name] = self[1] }
|
|
end,
|
|
}, { __index = Type })
|
|
|
|
for _, method_name in ipairs(methods) do
|
|
local method = impl[method_name]
|
|
|
|
if not method then
|
|
error(('%s method is missing for %s.%s'):format(method_name, name, constructor_name))
|
|
end
|
|
obj[method_name] = method
|
|
impl[method_name] = nil -- so we can tell if there are any extras...
|
|
end
|
|
|
|
local extra = next(impl)
|
|
if extra then
|
|
error(('%s method is unexpected for %s.%s'):format(extra, name, constructor_name))
|
|
end
|
|
return function(_, ...)
|
|
return setmetatable({ ... }, {
|
|
__index = obj,
|
|
__call = function(_, ...)
|
|
return Type[constructor_name](Type, ...)
|
|
end,
|
|
})
|
|
end
|
|
end
|
|
end
|
|
|
|
for constructor_name, impl in pairs(defs) do
|
|
Type[constructor_name] = to_obj(constructor_name, impl)
|
|
end
|
|
return setmetatable(Type, {
|
|
__call = function(self, data, ...)
|
|
local constructor_name, value = next(data)
|
|
local constructor = self[constructor_name]
|
|
if not constructor then
|
|
error(('Invalid %s constructor: %s'):format(name, constructor_name))
|
|
end
|
|
return constructor(self, value, ...)
|
|
end,
|
|
})
|
|
end
|