Release 0.1.0

This commit is contained in:
xeon
2026-02-02 20:53:22 +03:00
commit 25660300dd
152 changed files with 882089 additions and 0 deletions

90
common/src/args.zig Normal file
View File

@@ -0,0 +1,90 @@
const std = @import("std");
const meta = std.meta;
const enums = std.enums;
const Allocator = std.mem.Allocator;
const ArenaAllocator = std.heap.ArenaAllocator;
pub fn Parsed(comptime Args: type) type {
return struct {
const P = @This();
arena: ArenaAllocator,
options: Args,
pub fn deinit(p: P) void {
p.arena.deinit();
}
};
}
pub fn parseOrPrintUsageAlloc(comptime Args: type, gpa: std.mem.Allocator, args: std.process.Args) ?Parsed(Args) {
var arena: ArenaAllocator = .init(gpa);
const args_slice = args.toSlice(arena.allocator()) catch return null;
const parsed_args = parse(Args, args_slice[1..]) orelse {
printUsage(Args, args_slice[0]);
arena.deinit();
return null;
};
return .{
.arena = arena,
.options = parsed_args,
};
}
pub fn parse(comptime Args: type, args: []const [:0]const u8) ?Args {
const fields = @typeInfo(Args).@"struct".fields;
const ArgField = comptime meta.FieldEnum(Args);
const Flag = comptime blk: {
const field_names = meta.fieldNames(ArgField);
var flags: [field_names.len]u8 = undefined;
for (field_names, 0..) |name, i| {
flags[i] = name[0];
}
break :blk @Enum(u8, .exhaustive, field_names, &flags);
};
var result: Args = .{};
var arg_stack_buffer: [fields.len]Flag = undefined;
var arg_stack = std.ArrayList(Flag).initBuffer(arg_stack_buffer[0..]);
for (args) |arg| {
if (arg[0] == '-') {
for (arg[1..]) |flag| {
if (arg_stack.items.len == fields.len) return null;
arg_stack.appendAssumeCapacity(std.enums.fromInt(Flag, flag) orelse return null);
}
} else {
if (arg_stack.items.len == 0) return null;
switch (arg_stack.swapRemove(0)) {
inline else => |flag| @field(result, @tagName(flag)) = arg,
}
}
}
return if (arg_stack.items.len == 0) result else null;
}
pub fn printUsage(comptime Args: type, program_name: []const u8) void {
const usage_string = comptime blk: {
var fmt: []const u8 = "Usage: {s} [-";
for (@typeInfo(Args).@"struct".fields) |field| {
fmt = fmt ++ .{field.name[0]};
}
fmt = fmt ++ "] ";
for (@typeInfo(Args).@"struct".fields) |field| {
fmt = fmt ++ "[" ++ field.name ++ "] ";
}
break :blk fmt ++ "\n";
};
std.debug.print(usage_string, .{program_name});
}

1
common/src/io.zig Normal file
View File

@@ -0,0 +1 @@
pub const Poll = @import("io/poll.zig").Poll;

2605
common/src/io/poll.zig Normal file

File diff suppressed because it is too large Load Diff

47
common/src/mem.zig Normal file
View File

@@ -0,0 +1,47 @@
const std = @import("std");
pub fn LimitedString(comptime limit: usize) type {
return struct {
const String = @This();
pub const max_length = limit;
pub const empty: String = .{};
bytes: [max_length + 1]u8 = @splat(0),
pub fn init(value: []const u8) error{TooLongString}!String {
var string: String = .{};
try string.set(value);
return string;
}
pub fn constant(comptime value: []const u8) String {
errdefer comptime unreachable; // Constant string literal is too long.
return try comptime String.init(value);
}
pub fn view(string: *const String) [:0]const u8 {
std.debug.assert(string.bytes[max_length] == 0);
return std.mem.span(@as([*:0]const u8, @ptrCast(&string.bytes)));
}
pub fn set(string: *String, value: []const u8) error{TooLongString}!void {
if (value.len > max_length) return error.TooLongString;
@memcpy(string.bytes[0..value.len], value);
string.bytes[value.len] = 0;
}
pub fn jsonStringify(string: *const String, jws: anytype) !void {
try jws.write(string.view());
}
pub fn jsonParse(a: std.mem.Allocator, source: anytype, options: std.json.ParseOptions) !String {
return switch (try source.nextAlloc(a, options.allocate.?)) {
inline .string, .allocated_string => |string| String.init(string) catch error.LengthMismatch,
else => return error.UnexpectedToken,
};
}
};
}

3
common/src/root.zig Normal file
View File

@@ -0,0 +1,3 @@
pub const io = @import("io.zig");
pub const args = @import("args.zig");
pub const mem = @import("mem.zig");