diff options
| -rw-r--r-- | lua/clever_f/domain.lua | 54 | ||||
| -rw-r--r-- | tests/run.lua | 9 |
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) |
