From fd8d800cf04d73bb687fbc51fb2123282b0345e0 Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Thu, 29 Dec 2016 12:11:48 +0100 Subject: [PATCH] Minor restructure. --- pretty.lua | 85 ++++++++++++++++++++++++-------------------- test/test_pretty.lua | 5 +++ 2 files changed, 52 insertions(+), 38 deletions(-) diff --git a/pretty.lua b/pretty.lua index a7bf1c9..3f4c0b6 100644 --- a/pretty.lua +++ b/pretty.lua @@ -1,8 +1,15 @@ +local TABLE_TYPE_EMPTY = 'EMPTY TABLE' local TABLE_TYPE_SEQUENCE = 'SEQUENCE' +local TABLE_TYPE_STRING_MAP = 'STRING KEY MAP' local TABLE_TYPE_PURE_MAP = 'PURE MAP' local TABLE_TYPE_MIXED = 'MIXED TABLE' -local TABLE_TYPE_EMPTY = 'EMPTY TABLE' + +local SINGLE_LINE_TABLE_TYPES = { + [TABLE_TYPE_SEQUENCE] = true, + [TABLE_TYPE_PURE_MAP] = true, + [TABLE_TYPE_STRING_MAP] = true, +} local SINGLE_LINE_SEQ_MAX_ELEMENTS = 10 local SINGLE_LINE_MAP_MAX_ELEMENTS = 5 @@ -72,11 +79,6 @@ local function alphanum_compare_strings (a, b) < tostring(b):gsub("%.?%d+", padnum)..("%3d"):format(#a) end -local function count_occurances_of_substring_in_string (str, substr) - local _, count = string.gsub(str, substr, '') - return count -end - local function smallest_secure_longform_string_level (str) -- Determines the level a longform string needs to use, to avoid "code" -- injection. For example, if we want to use longform on the string @@ -149,6 +151,20 @@ local function contains_only_nice_string_keys (t) return true end +local function contains_only_nice_number_indexes (t) + -- A "nice" index is here defined as one which would be visited when using + -- ipairs: An integer larger than 1 and less than #t + + local max_index = #t + for k, v in pairs(t) do + if type(k) ~= 'number' or k < 1 or max_index < k or k ~= math.floor(k) then + return false + end + end + + return true +end + local function escape_string (str) local l = {} for i = 1, #str do @@ -210,25 +226,15 @@ local function get_table_type (value) if is_empty_table(value) then return TABLE_TYPE_EMPTY end - local not_sequence = false - local not_pure_map = (#value ~= 0) - local max_index = #value - - -- Determine if there exist some non-index - for k, v in pairs(value) do - if type(k) ~= 'number' or k < 1 or max_index < k or k ~= math.floor(k) then - not_sequence = true - break - end - end + local is_sequence = contains_only_nice_number_indexes(value) + local only_string_keys = contains_only_nice_string_keys(value) + local is_pure_map = (#value == 0) -- Return type - if not not_sequence then - return TABLE_TYPE_SEQUENCE - elseif not_pure_map then - return TABLE_TYPE_MIXED - else - return TABLE_TYPE_PURE_MAP + if is_sequence then return TABLE_TYPE_SEQUENCE + elseif only_string_keys then return TABLE_TYPE_STRING_MAP + elseif is_pure_map then return TABLE_TYPE_PURE_MAP + else return TABLE_TYPE_MIXED end end @@ -242,8 +248,9 @@ local function is_single_line_table (value) local table_type = get_table_type(value) return not contains_non_simple_key_or_value(value) - and(table_type == TABLE_TYPE_SEQUENCE and #value <= SINGLE_LINE_SEQ_MAX_ELEMENTS - or table_type == TABLE_TYPE_PURE_MAP and nr_elements_in_map(value) <= SINGLE_LINE_MAP_MAX_ELEMENTS) + and SINGLE_LINE_TABLE_TYPES[table_type] + and #value <= SINGLE_LINE_SEQ_MAX_ELEMENTS + and nr_elements_in_map(value) <= SINGLE_LINE_MAP_MAX_ELEMENTS end -------------------------------------------------------------------------------- @@ -273,21 +280,21 @@ local function format_key_and_value_sequence (l, key, value, options, depth) l[#l+1] = format_value(value, options, depth) end -local function get_pair_format_func (t) - local table_type = get_table_type(t) - if table_type == TABLE_TYPE_SEQUENCE then return format_key_and_value_sequence - elseif contains_only_nice_string_keys(t) then return format_key_and_value_string_map - end - return format_key_and_value_arbitr_map -end +local TABLE_TYPE_TO_PAIR_FORMAT = { + [TABLE_TYPE_SEQUENCE] = format_key_and_value_sequence, + [TABLE_TYPE_STRING_MAP] = format_key_and_value_string_map, + [TABLE_TYPE_PURE_MAP] = format_key_and_value_arbitr_map, + [TABLE_TYPE_MIXED] = format_key_and_value_arbitr_map, +} -- Formatting tables local function format_single_line_map (t, options) -- NOTE: Assumes that the input table was pre-checked with `is_single_line_table()` - local key_value_pairs = get_key_value_pairs_in_proper_order(t) - local pair_format_func = get_pair_format_func(t) + local key_value_pairs = get_key_value_pairs_in_proper_order(t) + local table_type = get_table_type(t) + local pair_format_func = TABLE_TYPE_TO_PAIR_FORMAT[table_type] local l = {'{ '} local top_before = #l @@ -311,9 +318,10 @@ end local function format_map (t, options, depth) - local key_value_pairs = get_key_value_pairs_in_proper_order(t) - local pair_format_func = get_pair_format_func(t) - + local key_value_pairs = get_key_value_pairs_in_proper_order(t) + local table_type = get_table_type(t) + local pair_format_func = TABLE_TYPE_TO_PAIR_FORMAT[table_type] + -- Figure out the max key length local l = {'{\n'} local top_before = #l @@ -336,7 +344,8 @@ local function format_map (t, options, depth) end end - l[#l] = '\n' + if l[#l] == ',\n' then l[#l] = nil end + l[#l+1] = '\n' l[#l+1] = options.indent:rep(depth) l[#l+1] = '}' return table.concat(l, '') diff --git a/test/test_pretty.lua b/test/test_pretty.lua index b7a05cf..cdd6253 100644 --- a/test/test_pretty.lua +++ b/test/test_pretty.lua @@ -276,6 +276,11 @@ format_test { expect = '{\n\t[true] = 1,\n\t[1] = false\n}', } +format_test { + input = { [1] = 1, ['whatever'] = false }, + expect = '{\n\t[1] = 1,\n\t[\'whatever\'] = false\n}', +} + -------------------------------------------------------------------------------- return SUITE