pgmql/lib/utils/comptime.zig

69 lines
2.2 KiB
Zig

const std = @import("std");
/// Append an element to the given array at comptime.
pub fn append(array: anytype, element: anytype) @TypeOf(array ++ .{element}) {
return array ++ .{element};
}
/// Join strings into one, with the given separator in between.
pub fn join(separator: []const u8, slices: []const[]const u8) []const u8 {
if (slices.len == 0) return "";
// Compute total length of the string to make.
const totalLen = total: {
// Compute separator length.
var total = separator.len * (slices.len - 1);
// Add length of all slices.
for (slices) |slice| total += slice.len;
break :total total;
};
var buffer: [totalLen]u8 = undefined;
// Based on std.mem.joinMaybeZ implementation.
@memcpy(buffer[0..slices[0].len], slices[0]);
var buf_index: usize = slices[0].len;
for (slices[1..]) |slice| {
@memcpy(buffer[buf_index .. buf_index + separator.len], separator);
buf_index += separator.len;
@memcpy(buffer[buf_index .. buf_index + slice.len], slice);
buf_index += slice.len;
}
// Put final buffer in a const variable to allow to use its value at runtime.
const finalBuffer = buffer;
return &finalBuffer;
}
/// Convert a PascalCased identifier to a kebab-cased identifier.
pub fn pascalToKebab(comptime pascalIdentifier: []const u8) []const u8 {
// Array of all parts of the identifier (separated by uppercased characters).
var parts: []const []const u8 = &[0][]const u8{};
// The current identifier part.
var currentPart: []const u8 = &[0]u8{};
for (pascalIdentifier) |pascalChar| {
// For each character...
if (std.ascii.isUpper(pascalChar)) {
// ... if it's uppercased, save the current part and initialize a new one.
if (currentPart.len > 0) {
// If the current part length is bigger than 0, save it.
parts = append(parts, currentPart);
}
// Create a new part, with the lowercased character.
currentPart = &[1]u8{std.ascii.toLower(pascalChar)};
} else {
// ... append the current (not uppercased) character to the current part.
currentPart = append(currentPart, pascalChar);
}
}
// Append the last current part to parts list.
if (currentPart.len > 0) {
parts = append(parts, currentPart);
}
// Join all the parts with "-" to create a kebab-cased identifier.
return join("-", parts);
}