From 840524534b352429958b8c1162f78b15fb81589b Mon Sep 17 00:00:00 2001 From: Tyler Miller Date: Sat, 13 Jul 2024 07:22:50 -0700 Subject: [PATCH] fix(template): don't use `str[1]` to get 1st char In Lua, `str[1]` on a string always returns `nil`. Use `str:find('^#')` instead of `str[1] == '#'` to check the first byte/char. --- lua/github-theme/util/template.lua | 45 +++++++++++++++--------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/lua/github-theme/util/template.lua b/lua/github-theme/util/template.lua index bd0d74bd..199732c7 100644 --- a/lua/github-theme/util/template.lua +++ b/lua/github-theme/util/template.lua @@ -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 (table). +---@param template table a table holding placeholders +---@param spec table a table to resolve placeholders against +---@return table # a new table where all placeholders have been resolved/replaced 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 @@ -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