z_mirror/flib

git clone https://git.raiguard.me/z_mirror/flib

Caleb HeuerRemove require guardsa9f2be7

trunk
2.4 KiB84 linesraw
1--- Various string formatting functions.
2--- ```lua
3--- local flib_format = require("__flib__.format")
4--- ```
5--- @class flib_format
6local flib_format = {}
7
8local suffix_list = {
9  { "Q", 1e30 }, -- quetta
10  { "R", 1e27 }, -- ronna
11  { "Y", 1e24 }, -- yotta
12  { "Z", 1e21 }, -- zetta
13  { "E", 1e18 }, -- exa
14  { "P", 1e15 }, -- peta
15  { "T", 1e12 }, -- tera
16  { "G", 1e9 }, -- giga
17  { "M", 1e6 }, -- mega
18  { "k", 1e3 }, -- kilo
19}
20
21--- Format a number for display, adding commas and an optional SI suffix.
22--- Specify `fixed_precision` to display the number with the given width,
23--- adjusting precision as necessary.
24--- @param amount number
25--- @param append_suffix boolean?
26--- @param fixed_precision number?
27--- @return string
28function flib_format.number(amount, append_suffix, fixed_precision)
29  local suffix = ""
30  if append_suffix then
31    for _, data in ipairs(suffix_list) do
32      if math.abs(amount) >= data[2] then
33        amount = amount / data[2]
34        suffix = " " .. data[1]
35        break
36      end
37    end
38    if not fixed_precision then
39      amount = math.floor(amount * 10) / 10
40    end
41  end
42  local formatted, k = tostring(amount), nil
43  if fixed_precision then
44    -- Show the number with fixed width precision
45    local len_before = #tostring(math.floor(amount))
46    local len_after = math.max(0, fixed_precision - len_before - 1)
47    formatted = string.format("%." .. len_after .. "f", amount)
48  end
49  -- Add commas to result
50  while true do
51    formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", "%1,%2")
52    if k == 0 then
53      break
54    end
55  end
56  return formatted .. suffix
57end
58
59--- Convert the given tick or game.tick into "[hh:]mm:ss" format.
60--- @param tick uint?
61--- @param include_leading_zeroes boolean?
62--- @return string
63function flib_format.time(tick, include_leading_zeroes)
64  local total_seconds = math.floor((tick or game.ticks_played) / 60)
65  local seconds = total_seconds % 60
66  local minutes = math.floor(total_seconds / 60)
67  if minutes > 59 then
68    minutes = minutes % 60
69    local hours = math.floor(total_seconds / 3600)
70    if include_leading_zeroes then
71      return string.format("%02d:%02d:%02d", hours, minutes, seconds)
72    else
73      return string.format("%d:%02d:%02d", hours, minutes, seconds)
74    end
75  else
76    if include_leading_zeroes then
77      return string.format("%02d:%02d", minutes, seconds)
78    else
79      return string.format("%d:%02d", minutes, seconds)
80    end
81  end
82end
83
84return flib_format