From 2c9a80e363a06797f1151bbf55b38e5909365cc7 Mon Sep 17 00:00:00 2001 From: Emil Lerch Date: Thu, 29 Feb 2024 13:43:48 -0800 Subject: [PATCH] update snake case to handle space followed by single character at end of string --- codegen/src/snake.zig | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/codegen/src/snake.zig b/codegen/src/snake.zig index 299d6a3..8f944a7 100644 --- a/codegen/src/snake.zig +++ b/codegen/src/snake.zig @@ -28,10 +28,22 @@ pub fn fromPascalCase(allocator: std.mem.Allocator, name: []const u8) ![]u8 { // prev_codepoint/ascii_prev_char (and target_inx) target_inx = setNext(lowercase(curr_char), rc, target_inx); target_inx = setNext('_', rc, target_inx); - curr_char = (try isAscii(utf8_name.nextCodepoint())).?; + var maybe_curr_char = (try isAscii(utf8_name.nextCodepoint())); + if (maybe_curr_char == null) { + std.log.err("Error on fromPascalCase processing name '{s}'", .{name}); + } + curr_char = maybe_curr_char.?; + maybe_curr_char = (try isAscii(utf8_name.nextCodepoint())); + if (maybe_curr_char == null) { + // We have reached the end of the string (e.g. "Resource Explorer 2") + // We need to do this check before we setNext, so that we don't + // end up duplicating the last character + break; + // std.log.err("Error on fromPascalCase processing name '{s}', curr_char = '{}'", .{ name, curr_char }); + } target_inx = setNext(lowercase(curr_char), rc, target_inx); prev_char = curr_char; - curr_char = (try isAscii(utf8_name.nextCodepoint())).?; + curr_char = maybe_curr_char.?; continue; } if (between(curr_char, 'A', 'Z')) { @@ -60,6 +72,7 @@ pub fn fromPascalCase(allocator: std.mem.Allocator, name: []const u8) ![]u8 { target_inx = setNext(lowercase(curr_char), rc, target_inx); rc[target_inx] = 0; + _ = allocator.resize(rc, target_inx); return rc[0..target_inx]; } @@ -134,3 +147,11 @@ test "IoT 1Click Devices Service" { // turn into. Should it be iot_1click_... or iot_1_click...? try expectEqualStrings("iot_1_click_devices_service", snake_case); } +test "Resource Explorer 2" { + const allocator = std.testing.allocator; + const snake_case = try fromPascalCase(allocator, "Resource Explorer 2"); + defer allocator.free(snake_case); + // NOTE: There is some debate amoung humans about what this should + // turn into. Should it be iot_1click_... or iot_1_click...? + try expectEqualStrings("resource_explorer_2", snake_case); +}