repositories / dotfiles
dotfiles
bugabingas dorkfiles
owned by admin
neovim/lua/bugabinga/pivi/jsonl.lua
Rawlocal LF = '\n'
local strip_carriage_return = function( record )
if record:sub( -1 ) == '\r' then return record:sub( 1, -2 ) end
return record
end
--- Creates a strict JSONL record splitter.
--- Records are delimited by LF only. A trailing CR is stripped.
--- Unicode line separators inside JSON strings never split a record.
local new_splitter = function()
local pending = ''
--- @param chunk string? bytes received from the child process
--- @return string[] records complete records contained in the chunk
local feed = function( chunk )
local records = {}
if chunk == nil or chunk == '' then return records end
pending = pending .. chunk
while true do
local index = pending:find( LF, 1, true )
if not index then break end
local record = strip_carriage_return( pending:sub( 1, index - 1 ) )
pending = pending:sub( index + 1 )
if record ~= '' then table.insert( records, record ) end
end
return records
end
--- @return string[] records the unterminated remainder, if any
local finish = function()
local remainder = strip_carriage_return( pending )
pending = ''
if remainder == '' then return {} end
return { remainder, }
end
local buffered = function() return pending end
return {
feed = feed,
finish = finish,
buffered = buffered,
}
end
--- @param record string one complete JSONL record
--- @return table? value decoded object, or nil when the record is not a JSON object
--- @return string? error decode failure description
local parse = function( record )
local ok, value = pcall( vim.json.decode, record, { luanil = { object = true, array = true, }, } )
if not ok then return nil, tostring( value ) end
if type( value ) ~= 'table' then return nil, 'record is not a JSON object' end
return value, nil
end
return {
splitter = new_splitter,
parse = parse,
}