90 lines
3.2 KiB
Zig
90 lines
3.2 KiB
Zig
allocator: std.mem.Allocator,
|
|
table: Table,
|
|
|
|
const Table = std.StringHashMapUnmanaged(Info);
|
|
|
|
pub const Info = struct {
|
|
trigger_characters: std.ArrayList([]const u8) = .empty,
|
|
};
|
|
|
|
pub fn init(allocator: std.mem.Allocator) @This() {
|
|
return .{
|
|
.allocator = allocator,
|
|
.table = .empty,
|
|
};
|
|
}
|
|
|
|
pub fn deinit(self: *@This()) void {
|
|
var iter = self.table.iterator();
|
|
while (iter.next()) |item| {
|
|
for (item.value_ptr.trigger_characters.items) |char|
|
|
self.allocator.free(char);
|
|
item.value_ptr.trigger_characters.deinit(self.allocator);
|
|
self.allocator.free(item.key_ptr.*);
|
|
}
|
|
self.table.deinit(self.allocator);
|
|
}
|
|
|
|
pub fn add_from_event(self: *@This(), cbor_buf: []const u8) error{ InvalidTriggersArray, OutOfMemory }!void {
|
|
var iter = cbor_buf;
|
|
var project: []const u8 = undefined;
|
|
var lsp_arg0: []const u8 = undefined;
|
|
var trigger_characters: []const u8 = undefined;
|
|
if (!(cbor.matchValue(&iter, .{
|
|
cbor.any,
|
|
cbor.any,
|
|
cbor.extract(&project),
|
|
.{ cbor.extract(&lsp_arg0), cbor.more },
|
|
cbor.extract_cbor(&trigger_characters),
|
|
}) catch return)) return;
|
|
try self.add(lsp_arg0, &trigger_characters);
|
|
}
|
|
|
|
fn add(self: *@This(), lsp_arg0: []const u8, iter: *[]const u8) error{ InvalidTriggersArray, OutOfMemory }!void {
|
|
const key = try self.allocator.dupe(u8, lsp_arg0);
|
|
errdefer self.allocator.free(key);
|
|
|
|
const p = try self.table.getOrPut(self.allocator, key);
|
|
const value = p.value_ptr;
|
|
if (p.found_existing) {
|
|
for (value.trigger_characters.items) |char|
|
|
self.allocator.free(char);
|
|
value.trigger_characters.clearRetainingCapacity();
|
|
} else {
|
|
value.* = .{};
|
|
}
|
|
|
|
var len = cbor.decodeArrayHeader(iter) catch return error.InvalidTriggersArray;
|
|
while (len > 0) : (len -= 1) {
|
|
var char: []const u8 = undefined;
|
|
if (!(cbor.matchValue(iter, cbor.extract(&char)) catch return error.InvalidTriggersArray)) return error.InvalidTriggersArray;
|
|
(try value.trigger_characters.addOne(self.allocator)).* = try self.allocator.dupe(u8, char);
|
|
}
|
|
}
|
|
|
|
pub fn write_state(self: *@This(), writer: *std.Io.Writer) error{WriteFailed}!void {
|
|
try cbor.writeArrayHeader(writer, self.table.count());
|
|
var iter = self.table.iterator();
|
|
while (iter.next()) |item| {
|
|
try cbor.writeArrayHeader(writer, 2);
|
|
try cbor.writeValue(writer, item.key_ptr.*);
|
|
try cbor.writeArrayHeader(writer, item.value_ptr.trigger_characters.items.len);
|
|
for (item.value_ptr.trigger_characters.items) |char| try cbor.writeValue(writer, char);
|
|
}
|
|
}
|
|
|
|
pub fn extract_state(self: *@This(), iter: *[]const u8) error{ InvalidTriggersArray, OutOfMemory }!void {
|
|
var lsp_arg0: []const u8 = undefined;
|
|
var trigger_characters: []const u8 = undefined;
|
|
var len = cbor.decodeArrayHeader(iter) catch return;
|
|
while (len > 0) : (len -= 1) {
|
|
if (cbor.matchValue(iter, .{ cbor.extract(&lsp_arg0), cbor.extract_cbor(&trigger_characters) }) catch false) {
|
|
try self.add(lsp_arg0, &trigger_characters);
|
|
} else {
|
|
cbor.skipValue(iter) catch return error.InvalidTriggersArray;
|
|
}
|
|
}
|
|
}
|
|
|
|
const std = @import("std");
|
|
const cbor = @import("cbor");
|