Skip to content

Commit

Permalink
fix(template): don't use str[1] to get 1st char
Browse files Browse the repository at this point in the history
In Lua, `str[1]` on a string always returns `nil`. Use `str:find('^#')`
instead of `str[1] == '#'` to check the first byte/char.
  • Loading branch information
tmillr committed Jul 13, 2024
1 parent da7281e commit e2cc3fe
Showing 1 changed file with 23 additions and 22 deletions.
45 changes: 23 additions & 22 deletions lua/github-theme/util/template.lua
Original file line number Diff line number Diff line change
@@ -1,51 +1,52 @@
local M = {}

---Walk path (one.two.three) in a table and return value
---Walks/resolves keypath (one.two.three) against a table and returns the result.
---@param t table
---@param path string
---@param keypath string
---@return any
local function get_path(t, path)
for segment in path:gmatch('[^.]+') do
if type(t) == 'table' then
t = t[segment]
local function get_keypath(t, keypath)
for segment in keypath:gmatch('[^.]+') do
if type(t) ~= 'table' then
return t
end

t = t[segment]
end

return t
end

---Parse string for configuration template
---Parses and resolves keypath string for configuration template.
---@param str string
---@param spec Spec
---@return any
local function parse_string(str, spec)
if str == '' then
local function parse_keypath(str, spec)
if type(str) ~= 'string' or str == '' or str:find('^#') then
return str
end

if str[1] == '#' then
return str
end

local path = get_path(spec, str)
return path and path.base and path.base or path or str
local path = get_keypath(spec, str)
return path and (path.base or path) or str
end

---Resolves any and all placeholders in a template.
---@param template table a table holding placeholders
---@param spec table a table to resolve placeholders against
---@return table
function M.parse(template, spec)
local result = {}

for group, opts in pairs(template) do
if type(opts) == 'table' then
local new = {}

for key, value in pairs(opts) do
if type(value) == 'string' then
new[key] = parse_string(value, spec)
elseif type(value) == 'number' then
new[key] = value
end
new[key] = parse_keypath(value, spec)
end

result[group] = new
else
result[group] = parse_string(opts, spec)
result[group] = parse_keypath(opts, spec)
end
end

Expand All @@ -56,7 +57,7 @@ function M.parse_template_str(template, spec)
return (
template:gsub('($%b{})', function(w)
local path = w:sub(3, -2)
local value = get_path(spec, path) or w
local value = get_keypath(spec, path) or w
if type(value) == 'table' then
return value.base and value.base or value
else
Expand Down

0 comments on commit e2cc3fe

Please sign in to comment.