pub const PackageOptions = struct {
pub const Map = std.array_hash_map.String(UserProvided);
pub const UserProvided = union(enum) {
flag: void,
scalar: []const u8,
list: std.ArrayList([]const u8),
map: std.array_hash_map.String(*const UserProvided),
lazy_path: LazyPath,
lazy_path_list: std.ArrayList(LazyPath),
fn eql(a: UserProvided, b: UserProvided) bool {
if (std.meta.activeTag(a) != b) return false;
return switch (a) {
.flag => true,
.scalar => |a_scalar| return mem.eql(u8, a_scalar, b.scalar),
.list => |a_list| {
if (a_list.items.len != b.list.items.len) return false;
for (a_list.items, b.list.items) |a_elem, b_elem| {
if (!mem.eql(u8, a_elem, b_elem))
return false;
}
return true;
},
.map => |a_map| {
if (a_map.count() != b.map.count()) return false;
for (a_map.keys(), a_map.values(), b.map.keys(), b.map.values()) |a_key, a_val, b_key, b_val| {
if (!mem.eql(u8, a_key, b_key)) return false;
if (!a_val.eql(b_val.*)) return false;
}
return true;
},
.lazy_path => |a_lazy_path| return a_lazy_path.eql(b.lazy_path),
.lazy_path_list => |a_lazy_path_list| {
if (a_lazy_path_list.items.len != b.lazy_path_list.items.len) return false;
for (a_lazy_path_list.items, b.lazy_path_list.items) |a_lp, b_lp| {
if (!a_lp.eql(b_lp)) return false;
}
return true;
},
};
}
fn hash(a: UserProvided, hasher: *std.hash.Wyhash) void {
hasher.update(&mem.toBytes(std.meta.activeTag(a)));
switch (a) {
.flag => {},
.scalar => |scalar| hasher.update(scalar),
.list => |*list| for (list.items) |elem| hasher.update(elem),
.map => |*map| for (map.keys(), map.values()) |key, val| {
hasher.update(key);
val.hash(hasher);
},
.lazy_path => |lp| lp.hash(hasher),
.lazy_path_list => |*list| for (list.items) |lp| lp.hash(hasher),
}
}
};
fn fromArgs(arena: Allocator, map: *PackageOptions.Map, args: anytype) void {
const args_info = @typeInfo(@TypeOf(args)).@"struct";
inline for (args_info.field_names, args_info.field_types) |field_name, field_type| {
if (field_type == @TypeOf(null)) continue;
addPackageOptionFromArg(arena, map, field_name, field_type, @field(args, field_name));
}
}
pub fn sort(map: *Map) void {
map.sortUnstable(@as(struct {
keys: []const []const u8,
pub fn lessThan(this: @This(), a_index: usize, b_index: usize) bool {
return mem.lessThan(u8, this.keys[a_index], this.keys[b_index]);
}
}, .{ .keys = map.keys() }));
}
}
Build system implementation details.