Skip to content

Commit

Permalink
feat: initial statistics implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Rasmus-Bertell committed Nov 25, 2023
1 parent 0d22f4a commit 091d160
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 1 deletion.
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ have to leave Neovim!

- System-wide
- curl
- Optional [can be changed, see config bellow]
- Optional [can be changed, see config below]
- jq (to format JSON output)
- tidy (to format HTML output)
- Other plugins
Expand Down Expand Up @@ -83,6 +83,9 @@ use {
show_curl_command = false,
show_http_info = true,
show_headers = true,
-- table of curl `--write-out` variables or false if disabled
-- for more granular control see Statistics Spec
show_statistics = false,
-- executables or functions for formatting response body [optional]
-- set them to false if you want to disable them
formatters = {
Expand Down Expand Up @@ -154,6 +157,16 @@ To run `rest.nvim` you should map the following commands:
- `custom_dynamic_variables` allows to extend or overwrite built-in dynamic variable functions
(default: {})

### Statistics Spec

| Property | Type | Description |
| :------- | :-------------- | :----------------------------------------------------- |
| [1] | string | `--write-out` variable name, see `man curl`. Required. |
| title | string | Replaces the variable name in the output if defined. |
| type | string|function | Specifies type transformation for the output value.
Default transformers are `time` and `byte`. Can also be a function which takes the
value as a parameter and returns a string. |

## Usage

Create a new http file or open an existing one and place the cursor over the
Expand Down
1 change: 1 addition & 0 deletions lua/rest-nvim/config/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ local config = {
show_url = true,
show_http_info = true,
show_headers = true,
show_statistics = false,
formatters = {
json = "jq",
html = function(body)
Expand Down
9 changes: 9 additions & 0 deletions lua/rest-nvim/curl/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,15 @@ local function create_callback(curl_cmd, opts)
end
end

if config.get("result").show_statistics then
-- Statistics, e.g. Total Time: 123.4 ms
local statistics

res.body, statistics = utils.parse_statistics(res.body)

utils.write_block(res_bufnr, statistics, true)
end

--- Add the curl command results into the created buffer
local formatter = config.get("result").formatters[content_type]
-- format response body
Expand Down
17 changes: 17 additions & 0 deletions lua/rest-nvim/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,23 @@ rest.run_request = function(req, opts)
spliced_body = splice_body(result.headers, result.body)
end

if config.get("result").show_statistics then
local statistics_line = {}

for _, tbl in ipairs(config.get("result").show_statistics) do
if type(tbl) == "string" then
tbl = { tbl }
end

table.insert(statistics_line, tbl[1] .. "=%{" .. tbl[1] .. "}")
end

curl_raw_args = vim.tbl_extend("force", curl_raw_args, {
"--write-out",
"\\n" .. table.concat(statistics_line, "&"),
})
end

Opts = {
request_id = vim.loop.now(), -- request id used to correlate RestStartRequest and RestStopRequest events
method = result.method:lower(),
Expand Down
100 changes: 100 additions & 0 deletions lua/rest-nvim/utils/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,106 @@ M.split_list = function(tbl, index, inclusive)
return out
end

--- Default transformers for statistics
local transform = {
time = function(time)
time = tonumber(time)

if time >= 60 then
time = string.format("%.2f", time / 60)

return time .. " min"
end

local units = { "s", "ms", "µs", "ns" }
local unit = 1

while time < 1 and unit <= #units do
time = time * 1000
unit = unit + 1
end

time = string.format("%.2f", time)

return time .. " " .. units[unit]
end,

byte = function(bytes)
bytes = tonumber(bytes)

local units = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB" }
local unit = 1

while bytes >= 1024 and unit <= #units do
bytes = bytes / 1024
unit = unit + 1
end

bytes = string.format("%.2f", bytes)

return bytes .. " " .. units[unit]
end,
}

--- Parse statistics line to a table with key, value pairs
---
--- @param statistics_line string The statistics line from body
---
--- @return string[] statistics
local get_parsed_statistics = function(statistics_line)
local out = {}

for _, statistics_pair in ipairs(M.split(statistics_line, "&")) do
local value = M.split(statistics_pair, "=", 1)

if #value == 1 then
table.insert(out, value[1])
else
out[value[1]] = value[2]
end
end

return out
end

--- Parse and transform statistics line to a table of strings to be output.
--- Returns the body without statistics line and a table of statistics lines.
---
--- @param body string Response body
---
--- @return string body, string[] statistics
M.parse_statistics = function(body)
local _, _, statistics = string.find(body, "[%c%s]+([^%c]*)$")
local config_statistics = config.get("result").show_statistics

body = string.gsub(body, "[%c%s]+([^%c]*)$", "")
local out = {}

statistics = get_parsed_statistics(statistics)

for _, tbl in ipairs(config_statistics) do
if type(tbl) == "string" then
tbl = { tbl }
end

local value = statistics[tbl[1]]

if tbl.type then
if type(tbl.type) == "string" then
value = transform[tbl.type](value)
end

if type(tbl.type) == "function" then
value = tbl.type(value)
end
end

table.insert(out, (tbl.title or (tbl[1] .. " ")) .. value)
end

return body, out
end

-- http_status returns the status code and the meaning, e.g. 200 OK
-- see https://httpstatuses.com/ for reference
-- @param code The request status code
Expand Down

0 comments on commit 091d160

Please sign in to comment.