╭ changed ────╮ │src/event.zig│ ╰─────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────╮ │← previous│ ╰──────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1584 @field(event, field.name) = std.meta.stringToEnum(field.type, bytes) orelse return error.InvalidEnumTag; │ │1585 }, │ │1586 .optional => |optional_info| { │ │1496 - if (optional_info.child != []const u8) @compileError("unsupported read field type: " ++ @typeName(field.type)); │ │1587 // a missing key is null │ │1498 - @field(event, field.name) = if (try map.getCursor(hash.hashInt(hash_kind, field.name))) |cursor| │ │1499 - try cursor.readBytesAlloc(arena.allocator(), null) │ │1500 - else │ │1501 - null; │ │1588 + if (try map.getCursor(hash.hashInt(hash_kind, field.name))) |cursor| { │ │1589 + if (optional_info.child == []const u8) { │ │1590 + @field(event, field.name) = try cursor.readBytesAlloc(arena.allocator(), null); │ │1591 + } else switch (@typeInfo(optional_info.child)) { │ │1592 + .array => |array_info| { │ │1593 + if (array_info.child != u8) @compileError("unsupported read field type: " ++ @typeName(field.type));│ │1594 + var bytes: optional_info.child = undefined; │ │1595 + const value = try cursor.readBytes(&bytes); │ │1596 + if (value.len != bytes.len) return error.InvalidByteArrayLength; │ │1597 + @field(event, field.name) = bytes; │ │1598 + }, │ │1599 + else => @compileError("unsupported read field type: " ++ @typeName(field.type)), │ │1600 + } │ │1601 + } else { │ │1602 + @field(event, field.name) = null; │ │1603 + } │ │1604 }, │ │1605 // a struct field's own fields are read from the same map │ │1606 .@"struct" => @field(event, field.name) = try read(field.type, DB, hash_kind, arena, map), │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────╮ │1645 } │ │1646 }, │ │1647 .bool, .int, .@"enum" => return a == b, │ │1648 + .optional => |optional_info| { │ │1649 + if (a) |a_value| { │ │1650 + if (b) |b_value| return fieldEqual(optional_info.child, a_value, b_value);│ │1651 + return false; │ │1652 + } │ │1653 + return b == null; │ │1654 + }, │ │1655 else => @compileError("unsupported field type: " ++ @typeName(Field)), │ │1656 } │ │1657 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1786 }, │ │1787 .@"enum" => try upsertBytes(DB, hash_kind, map, key, @tagName(value)), │ │1788 .optional => |optional_info| { │ │1680 - if (optional_info.child != []const u8) @compileError("unsupported upsert field type: " ++ @typeName(Field)); │ │1789 // a missing key is null │ │1682 - if (value) |bytes| { │ │1683 - try upsertBytes(DB, hash_kind, map, key, bytes); │ │1790 + if (value) |child| { │ │1791 + if (optional_info.child == []const u8) { │ │1792 + try upsertBytes(DB, hash_kind, map, key, child); │ │1793 + } else switch (@typeInfo(optional_info.child)) { │ │1794 + .array => |array_info| { │ │1795 + if (array_info.child != u8) @compileError("unsupported upsert field type: " ++ @typeName(Field));│ │1796 + try upsertBytes(DB, hash_kind, map, key, &child); │ │1797 + }, │ │1798 + else => @compileError("unsupported upsert field type: " ++ @typeName(Field)), │ │1799 + } │ │1800 } else { │ │1801 _ = try map.remove(key); │ │1802 } │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯