summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lua/clever_f/domain.lua54
-rw-r--r--tests/run.lua9
2 files changed, 54 insertions, 9 deletions
diff --git a/lua/clever_f/domain.lua b/lua/clever_f/domain.lua
index 4d21d56..0d802b3 100644
--- a/lua/clever_f/domain.lua
+++ b/lua/clever_f/domain.lua
@@ -786,20 +786,40 @@ function InputPacket.text(text)
})
end
-function InputPacket.raw_bytes(bytes)
+local function validated_packet_bytes(bytes, kind)
if type(bytes) ~= "table" or #bytes < 1 then
- fail("raw input bytes must be a nonempty list", 2)
+ fail(kind .. " bytes must be a nonempty list", 3)
end
local copy = {}
for index = 1, #bytes do
local byte = bytes[index]
if not is_integer(byte) or byte < 0 or byte > 255 then
- fail("raw input bytes must contain byte values", 2)
+ fail(kind .. " bytes must contain byte values", 3)
end
copy[index] = byte
end
+ return copy
+end
+
+local function bytes_from_string(value)
+ local bytes = {}
+ for index = 1, #value do
+ bytes[index] = string.byte(value, index)
+ end
+ return bytes
+end
+
+local function string_from_bytes(bytes)
+ local characters = {}
+ for index = 1, #bytes do
+ characters[index] = string.char(bytes[index])
+ end
+ return table.concat(characters)
+end
+
+function InputPacket.raw_bytes(bytes)
local identity = {}
- packet_bytes[identity] = copy
+ packet_bytes[identity] = validated_packet_bytes(bytes, "raw input")
return new_record("InputPacket", {
kind = M.InputPacketKind.RAW_BYTES,
identity = identity,
@@ -808,13 +828,24 @@ end
function InputPacket.special_key(name, encoded)
require_string(name, "special key name", false)
- if encoded ~= nil then
+ local bytes
+ if type(encoded) == "table" then
+ bytes = validated_packet_bytes(encoded, "special key")
+ encoded = string_from_bytes(bytes)
+ elseif encoded ~= nil then
require_string(encoded, "encoded special key", false)
+ bytes = bytes_from_string(encoded)
+ end
+ local identity
+ if bytes ~= nil then
+ identity = {}
+ packet_bytes[identity] = bytes
end
return new_record("InputPacket", {
kind = M.InputPacketKind.SPECIAL_KEY,
name = name,
encoded = encoded,
+ identity = identity,
})
end
@@ -841,7 +872,7 @@ function InputPacket.from_table(packet)
return InputPacket.raw_bytes(packet.bytes)
end
if kind == M.InputPacketKind.SPECIAL_KEY then
- return InputPacket.special_key(packet.name, packet.encoded)
+ return InputPacket.special_key(packet.name, packet.bytes or packet.encoded)
end
return InputPacket.error(packet.message)
end
@@ -851,10 +882,15 @@ function InputPacket.is(value)
end
function InputPacket:bytes()
- if self.kind ~= M.InputPacketKind.RAW_BYTES then
+ if self.kind ~= M.InputPacketKind.RAW_BYTES
+ and self.kind ~= M.InputPacketKind.SPECIAL_KEY
+ then
+ return nil
+ end
+ local source = self.identity and packet_bytes[self.identity] or nil
+ if source == nil then
return nil
end
- local source = packet_bytes[self.identity]
local result = {}
for index = 1, #source do
result[index] = source[index]
@@ -870,7 +906,7 @@ function InputPacket:to_table()
result.bytes = self:bytes()
elseif self.kind == M.InputPacketKind.SPECIAL_KEY then
result.name = self.name
- result.encoded = self.encoded
+ result.bytes = self:bytes()
else
result.message = self.message
end
diff --git a/tests/run.lua b/tests/run.lua
index 31c223e..61ab1ab 100644
--- a/tests/run.lua
+++ b/tests/run.lua
@@ -253,11 +253,20 @@ test("InputPacket carries every input capability variant", function()
local text = domain.InputPacket.text("a")
local bytes = domain.InputPacket.raw_bytes({ 0x80, 0xfd, 0x60 })
local special = domain.InputPacket.special_key("Left", string.char(0x80, 1))
+ local special_from_table = domain.InputPacket.from_table({
+ kind = "special_key",
+ name = "Escape",
+ bytes = { 27 },
+ })
local failure = domain.InputPacket.error("input failed")
same(domain.InputPacketKind.TEXT, text.kind)
list_same({ 0x80, 0xfd, 0x60 }, bytes:bytes())
same("Left", special.name)
+ list_same({ 0x80, 1 }, special:bytes())
+ same(string.char(27), special_from_table.encoded)
+ list_same({ 27 }, special_from_table:bytes())
+ list_same({ 27 }, special_from_table:to_table().bytes)
same("input failed", failure.message)
end)