1
0

Minor restructure.

This commit is contained in:
Jon Michael Aanes 2016-12-29 12:11:48 +01:00
parent c5f3bd4420
commit fd8d800cf0
2 changed files with 52 additions and 38 deletions

View File

@ -1,8 +1,15 @@
local TABLE_TYPE_EMPTY = 'EMPTY TABLE'
local TABLE_TYPE_SEQUENCE = 'SEQUENCE' local TABLE_TYPE_SEQUENCE = 'SEQUENCE'
local TABLE_TYPE_STRING_MAP = 'STRING KEY MAP'
local TABLE_TYPE_PURE_MAP = 'PURE MAP' local TABLE_TYPE_PURE_MAP = 'PURE MAP'
local TABLE_TYPE_MIXED = 'MIXED TABLE' 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_SEQ_MAX_ELEMENTS = 10
local SINGLE_LINE_MAP_MAX_ELEMENTS = 5 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) < tostring(b):gsub("%.?%d+", padnum)..("%3d"):format(#a)
end 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) local function smallest_secure_longform_string_level (str)
-- Determines the level a longform string needs to use, to avoid "code" -- Determines the level a longform string needs to use, to avoid "code"
-- injection. For example, if we want to use longform on the string -- 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 return true
end 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 function escape_string (str)
local l = {} local l = {}
for i = 1, #str do 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 if is_empty_table(value) then return TABLE_TYPE_EMPTY end
local not_sequence = false local is_sequence = contains_only_nice_number_indexes(value)
local not_pure_map = (#value ~= 0) local only_string_keys = contains_only_nice_string_keys(value)
local max_index = #value local is_pure_map = (#value == 0)
-- 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
-- Return type -- Return type
if not not_sequence then if is_sequence then return TABLE_TYPE_SEQUENCE
return TABLE_TYPE_SEQUENCE elseif only_string_keys then return TABLE_TYPE_STRING_MAP
elseif not_pure_map then elseif is_pure_map then return TABLE_TYPE_PURE_MAP
return TABLE_TYPE_MIXED else return TABLE_TYPE_MIXED
else
return TABLE_TYPE_PURE_MAP
end end
end end
@ -242,8 +248,9 @@ local function is_single_line_table (value)
local table_type = get_table_type(value) local table_type = get_table_type(value)
return not contains_non_simple_key_or_value(value) return not contains_non_simple_key_or_value(value)
and(table_type == TABLE_TYPE_SEQUENCE and #value <= SINGLE_LINE_SEQ_MAX_ELEMENTS and SINGLE_LINE_TABLE_TYPES[table_type]
or table_type == TABLE_TYPE_PURE_MAP and nr_elements_in_map(value) <= SINGLE_LINE_MAP_MAX_ELEMENTS) and #value <= SINGLE_LINE_SEQ_MAX_ELEMENTS
and nr_elements_in_map(value) <= SINGLE_LINE_MAP_MAX_ELEMENTS
end 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) l[#l+1] = format_value(value, options, depth)
end end
local function get_pair_format_func (t) local TABLE_TYPE_TO_PAIR_FORMAT = {
local table_type = get_table_type(t) [TABLE_TYPE_SEQUENCE] = format_key_and_value_sequence,
if table_type == TABLE_TYPE_SEQUENCE then return format_key_and_value_sequence [TABLE_TYPE_STRING_MAP] = format_key_and_value_string_map,
elseif contains_only_nice_string_keys(t) then return format_key_and_value_string_map [TABLE_TYPE_PURE_MAP] = format_key_and_value_arbitr_map,
end [TABLE_TYPE_MIXED] = format_key_and_value_arbitr_map,
return format_key_and_value_arbitr_map }
end
-- Formatting tables -- Formatting tables
local function format_single_line_map (t, options) local function format_single_line_map (t, options)
-- NOTE: Assumes that the input table was pre-checked with `is_single_line_table()` -- 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 key_value_pairs = get_key_value_pairs_in_proper_order(t)
local pair_format_func = get_pair_format_func(t) local table_type = get_table_type(t)
local pair_format_func = TABLE_TYPE_TO_PAIR_FORMAT[table_type]
local l = {'{ '} local l = {'{ '}
local top_before = #l local top_before = #l
@ -311,9 +318,10 @@ end
local function format_map (t, options, depth) local function format_map (t, options, depth)
local key_value_pairs = get_key_value_pairs_in_proper_order(t) local key_value_pairs = get_key_value_pairs_in_proper_order(t)
local pair_format_func = get_pair_format_func(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 -- Figure out the max key length
local l = {'{\n'} local l = {'{\n'}
local top_before = #l local top_before = #l
@ -336,7 +344,8 @@ local function format_map (t, options, depth)
end end
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] = options.indent:rep(depth)
l[#l+1] = '}' l[#l+1] = '}'
return table.concat(l, '') return table.concat(l, '')

View File

@ -276,6 +276,11 @@ format_test {
expect = '{\n\t[true] = 1,\n\t[1] = false\n}', 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 return SUITE