aboutsummaryrefslogtreecommitdiff
path: root/src/string_mutable.zig
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-05-07 23:34:16 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-05-07 23:34:16 -0700
commite70ac2ce825ecf5f2d6aa16152801612bf23be8d (patch)
tree3909a1f32e12051389180034ee027c19656efabb /src/string_mutable.zig
parent12615602144288b3123f352e5d586714bc01b4dc (diff)
downloadbun-e70ac2ce825ecf5f2d6aa16152801612bf23be8d.tar.gz
bun-e70ac2ce825ecf5f2d6aa16152801612bf23be8d.tar.zst
bun-e70ac2ce825ecf5f2d6aa16152801612bf23be8d.zip
wip
Former-commit-id: 79223472f7bb22c4de1f872a542f185aa7189aaa
Diffstat (limited to 'src/string_mutable.zig')
-rw-r--r--src/string_mutable.zig57
1 files changed, 36 insertions, 21 deletions
diff --git a/src/string_mutable.zig b/src/string_mutable.zig
index f142f5101..a5b13ca2e 100644
--- a/src/string_mutable.zig
+++ b/src/string_mutable.zig
@@ -15,16 +15,11 @@ pub const MutableString = struct {
}
pub fn growIfNeeded(self: *MutableString, amount: usize) !void {
- const new_capacity = self.list.items.len + amount;
- if (self.list.capacity < new_capacity) {
- try self.list.ensureCapacity(self.allocator, new_capacity);
- }
+ try self.list.ensureUnusedCapacity(self.allocator, amount);
}
pub fn writeAll(self: *MutableString, bytes: string) !usize {
- const new_capacity = self.list.items.len + bytes.len;
- try self.list.ensureCapacity(self.allocator, new_capacity);
- self.list.appendSliceAssumeCapacity(bytes);
+ try self.list.appendSlice(self.allocator, bytes);
return self.list.items.len;
}
@@ -47,26 +42,46 @@ pub const MutableString = struct {
return "_";
}
- var mutable = try MutableString.init(allocator, 0);
-
- var needsGap = false;
- for (str) |c| {
- if (std.ascii.isLower(c) or std.ascii.isUpper(c) or (mutable.len() > 0 and std.ascii.isAlNum(c))) {
- if (needsGap) {
- try mutable.appendChar('_');
- needsGap = false;
+ var has_needed_gap = false;
+ var needs_gap = false;
+ var start_i: usize = 0;
+
+ // Common case: no gap necessary. No allocation necessary.
+ needs_gap = std.ascii.isAlNum(str[0]);
+ if (!needs_gap) {
+ // Are there any non-alphanumeric chars at all?
+ for (str[1..str.len]) |c, i| {
+ switch (c) {
+ 'a'...'z', 'A'...'Z', '0'...'9' => {},
+ else => {
+ needs_gap = true;
+ start_i = i;
+ break;
+ },
}
- try mutable.appendChar(c);
- } else if (!needsGap) {
- needsGap = true;
}
}
- if (mutable.len() > 0) {
+ if (needs_gap) {
+ var mutable = try MutableString.initCopy(allocator, str[0..start_i]);
+
+ for (str[start_i..str.len]) |c, i| {
+ if (std.ascii.isLower(c) or std.ascii.isUpper(c) or (mutable.len() > 0 and std.ascii.isAlNum(c))) {
+ if (needs_gap) {
+ try mutable.appendChar('_');
+ needs_gap = false;
+ has_needed_gap = true;
+ }
+ try mutable.appendChar(c);
+ } else if (!needs_gap) {
+ needs_gap = true;
+ }
+ }
+
return mutable.list.toOwnedSlice(allocator);
- } else {
- return str;
}
+
+ return str;
}
pub fn len(self: *MutableString) usize {