From f5a9537db1d8973b283f01cb189550e52ac24702 Mon Sep 17 00:00:00 2001 From: Omkar Bhad <60899563+omkarbhad@users.noreply.github.com> Date: Wed, 29 Apr 2026 00:57:07 -0400 Subject: [PATCH] docs(key): document Key.text parser-scoped lifetime --- src/Key.zig | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Key.zig b/src/Key.zig index f2358383..638c1a3a 100644 --- a/src/Key.zig +++ b/src/Key.zig @@ -101,10 +101,16 @@ pub fn matchShiftedCodepoint(self: Key, cp: u21, mods: Modifiers) bool { } /// matches when the utf8 encoding of the codepoint and relevant mods matches the -/// text of the key. This function will consume Shift and Caps Lock when matching +/// text of the key. This function will consume Shift and Caps Lock when matching. +/// +/// Lifetime: `Key.text`, when set, points into the parser's per-event scratch +/// buffer and is only valid until the next event is decoded. Callers that +/// retain a `Key` past that point — for example, queueing events to another +/// thread — MUST copy the slice before doing so; otherwise both this routine +/// and any direct read of `text` race with the parser overwriting its buffer. pub fn matchText(self: Key, cp: u21, mods: Modifiers) bool { - // return early if we have no text - if (self.text == null) return false; + const text = self.text orelse return false; + if (text.len == 0) return false; var self_mods = self.mods; self_mods.num_lock = false; @@ -126,7 +132,7 @@ pub fn matchText(self: Key, cp: u21, mods: Modifiers) bool { var buf: [4]u8 = undefined; const n = std.unicode.utf8Encode(_cp, &buf) catch return false; - return std.mem.eql(u8, self.text.?, buf[0..n]) and std.meta.eql(self_mods, arg_mods); + return std.mem.eql(u8, text, buf[0..n]) and std.meta.eql(self_mods, arg_mods); } // The key must exactly match the codepoint and modifiers. caps_lock and