Welcome to the forum!
I agree that it’s weird that there is no realloc for sentinel-terminated slices.
Am I correct to assume that stringProvider
is the C API function and you have no control over that?
(if you have control over it I would just use an ArrayList instead, which has more safety)
For now I can only suggest you some less gross versions:
test "method 2 advanced: sentinel slicing" {
const buffer = try alloc.alloc(u8, 9000);
errdefer alloc.free(buffer);
const length = stringProvider(@ptrCast(buffer.ptr));
// less gross: no pointer cast and no length adjusting.
var minimal: [:0]u8 = (try alloc.realloc(buffer, length + 1))[0..length :0];
defer alloc.free(minimal);
try std.testing.expectEqualSentinel(u8, 0, target, minimal);
}
test "method 3 advanced: duplicate with less allocations" {
var buffer: [9000]u8 = undefined;
const length = stringProvider(@ptrCast(&buffer));
// less gross: Still always requires an extra memcpy, but we removed the first alloc by using the stack.
const minimal = try alloc.dupeZ(u8, buffer[0..length]);
defer alloc.free(minimal);
try std.testing.expectEqualSentinel(u8, 0, target, minimal);
}