Hi, ive been trying to get some formatting done where a writer.print() isnt enough. I am extremely frustated with this.
test authorPrint {
const authors = [_][]const u8{
"a",
"b",
"c",
"d",
};
try testing.expectEqualStrings("Written by a, b, c and d.\n", try authorPrint(&authors));
}
(if you can get the function working the test may fail from punctuation marks but thats not relevant)
Ive tried among a lot of things
naive array approach
fn authorPrint(comptime authors: []const []const u8) ![]const u8 {
if (authors.len == 0) {
return "";
}
var str: [1000:0]u8 = "Written by ";
for (authors, 1..) |author, i| {
if (i < 10) {
str = str ++ author;
if (i < authors.len - 1) {
str = str ++ ", ";
} else if (i == authors.len - 1) {
str = str ++ " and ";
}
} else {
str = str ++ " and others";
}
}
str = str ++ ".\n";
std.debug.print("{s}", .{str});
return str;
}
and array buffer print
fn authorPrint(comptime authors: []const []const u8) ![]const u8 {
if (authors.len == 0) {
return "";
}
var str: [1000:0]u8 = undefined;
var a: []u8 = try std.fmt.bufPrint(&str, "Written by ", .{});
for (authors, 1..) |author, i| {
if (i < 10) {
a = try std.fmt.bufPrint(&str, "{s} ", .{author});
if (i < authors.len - 1) {
a = try std.fmt.bufPrint(&str, ", ", .{});
} else if (i == authors.len - 1) {
a = try std.fmt.bufPrint(&str, " and ", .{});
}
} else {
a = try std.fmt.bufPrint(&str, " and others ", .{});
}
}
a = try std.fmt.bufPrint(&str, ".\n", .{});
std.debug.print("{s}", .{a});
return a;
}
and buffer with alocation
fn authorPrint(comptime authors: []const []const u8) ![]const u8 {
if (authors.len == 0) {
return "";
}
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
var string = std.ArrayList(u8).init(allocator);
defer string.deinit();
try string.appendSlice("Written by ");
for (authors, 1..) |author, i| {
if (i < 10) {
try string.appendSlice(author);
if (i < authors.len - 1) {
try string.appendSlice(", ");
} else if (i == authors.len - 1) {
try string.appendSlice(" and ");
}
} else {
try string.appendSlice(" and others");
}
}
try string.appendSlice(".\n");
std.debug.print("{s}", .{string.items});
return string.items;
}
and switch
fn authorPrint(comptime authors: []const []const u8) ![]const u8 {
const str = switch (authors.len) {
0 => "",
1 => "Written by {s}.\n",
2...9 => "Written by " ++ "{s}, " ** (authors.len - 1) ++ "and {s}.\n",
else => "Written by " ++ "{s}, " ** 10 ++ "and others.\n",
};
std.debug.print("{s}", .{str});
return std.fmt.comptimePrint(str, .{authors});
return "";
}
and comptimePrint, inline for loop…
no wonder the c code im using as reference literally just goes and switches the 10 cases