From dfb81e1c2edef08b2df98c6fd672ed33515dd313 Mon Sep 17 00:00:00 2001 From: prajwalch Date: Fri, 11 Oct 2024 15:36:45 +0545 Subject: [PATCH] fix(HelpMessageWriter): Handle word wrapping in `LineBlock.print()` Before this patch word wrapping was implemented, but only in the `LineBlock.writeAll()`. In this path we introduce the custom writer for the `LineBlock` with better error and word wrap handling. Signed-off-by: prajwalch --- src/HelpMessageWriter.zig | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/HelpMessageWriter.zig b/src/HelpMessageWriter.zig index 873005c..e1d15f1 100644 --- a/src/HelpMessageWriter.zig +++ b/src/HelpMessageWriter.zig @@ -281,6 +281,15 @@ fn LineBlock(comptime width: usize) type { const WHITE_SPACE = ' '; /// Used for storing content. const Array = std.BoundedArray(u8, width); + /// A custom writer over the `std.BoundedArray.Writer` for better error + /// and word wrap handling. + const ContentWriter = std.io.GenericWriter( + *Self, + ContentWriteError, + writeContent, + ); + /// Required error type for the required method. + const ContentWriteError = error{Overflow}; /// Content that fits into this block. visible_content: Array = Array{}, @@ -315,22 +324,35 @@ fn LineBlock(comptime width: usize) type { /// Appends the string based on the given format. fn print(self: *Self, comptime fmt: []const u8, args: anytype) !void { - try self.visible_content.writer().print(fmt, args); + try self.contentWriter().print(fmt, args); } /// Appends the given string as-is. fn writeAll(self: *Self, string: []const u8) !void { + try self.contentWriter().writeAll(string); + } + + /// Returns the content writer. + fn contentWriter(self: *Self) ContentWriter { + return ContentWriter{ .context = self }; + } + + /// Writes the given bytes and returns the number of bytes written. + fn writeContent(self: *Self, bytes: []const u8) ContentWriteError!usize { const remaining_space_length = self.remainingSpaceLength(); - if (string.len <= remaining_space_length) { - return self.visible_content.appendSlice(string); + if (bytes.len <= remaining_space_length) { + try self.visible_content.appendSlice(bytes); + return bytes.len; } - const writeable_portion = string[0..remaining_space_length]; + const writeable_portion = bytes[0..remaining_space_length]; try self.writeAll(writeable_portion); - const remaining_portion = string[remaining_space_length..]; + const remaining_portion = bytes[remaining_space_length..]; try self.overflow_content.appendSlice(remaining_portion); + + return writeable_portion.len; } pub fn format(