mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
Replace ExactSizeMatcher with bun.ComptimeStringMap
This refactoring removes the custom ExactSizeMatcher utility and replaces all usages with bun.ComptimeStringMap, which provides equivalent functionality with better maintainability. Changes: - Replace ExactSizeMatcher with bun.ComptimeStringMap in cli.zig - Replace ExactSizeMatcher with bun.ComptimeStringMap in Arguments.zig - Replace ExactSizeMatcher with bun.ComptimeStringMap in bunfig.zig - Replace ExactSizeMatcher with bun.ComptimeStringMap in integrity.zig - Remove ExactSizeMatcher export from immutable.zig - Delete exact_size_matcher.zig file 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -108,17 +108,17 @@ pub const Bunfig = struct {
|
||||
|
||||
fn loadLogLevel(this: *Parser, expr: js_ast.Expr) !void {
|
||||
try this.expectString(expr);
|
||||
const Matcher = strings.ExactSizeMatcher(8);
|
||||
const LogLevelMap = bun.ComptimeStringMap(api.MessageLevel, .{
|
||||
.{ "debug", api.MessageLevel.debug },
|
||||
.{ "error", api.MessageLevel.err },
|
||||
.{ "warn", api.MessageLevel.warn },
|
||||
.{ "info", api.MessageLevel.info },
|
||||
});
|
||||
|
||||
this.bunfig.log_level = switch (Matcher.match(expr.asString(this.allocator).?)) {
|
||||
Matcher.case("debug") => api.MessageLevel.debug,
|
||||
Matcher.case("error") => api.MessageLevel.err,
|
||||
Matcher.case("warn") => api.MessageLevel.warn,
|
||||
Matcher.case("info") => api.MessageLevel.info,
|
||||
else => {
|
||||
try this.addError(expr.loc, "Invalid log level, must be one of debug, error, or warn");
|
||||
unreachable;
|
||||
},
|
||||
const log_str = expr.asString(this.allocator).?;
|
||||
this.bunfig.log_level = LogLevelMap.get(log_str) orelse {
|
||||
try this.addError(expr.loc, "Invalid log level, must be one of debug, error, or warn");
|
||||
unreachable;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
124
src/cli.zig
124
src/cli.zig
@@ -539,79 +539,67 @@ pub const Command = struct {
|
||||
}
|
||||
|
||||
const first_arg_name = next_arg;
|
||||
const RootCommandMatcher = strings.ExactSizeMatcher(12);
|
||||
|
||||
return switch (RootCommandMatcher.match(first_arg_name)) {
|
||||
RootCommandMatcher.case("init") => .InitCommand,
|
||||
RootCommandMatcher.case("build"), RootCommandMatcher.case("bun") => .BuildCommand,
|
||||
RootCommandMatcher.case("discord") => .DiscordCommand,
|
||||
RootCommandMatcher.case("upgrade") => .UpgradeCommand,
|
||||
RootCommandMatcher.case("completions") => .InstallCompletionsCommand,
|
||||
RootCommandMatcher.case("getcompletes") => .GetCompletionsCommand,
|
||||
RootCommandMatcher.case("link") => .LinkCommand,
|
||||
RootCommandMatcher.case("unlink") => .UnlinkCommand,
|
||||
RootCommandMatcher.case("x") => .BunxCommand,
|
||||
RootCommandMatcher.case("repl") => .ReplCommand,
|
||||
|
||||
RootCommandMatcher.case("i"),
|
||||
RootCommandMatcher.case("install"),
|
||||
=> brk: {
|
||||
for (args_iter.buf) |arg| {
|
||||
if (arg.len > 0 and (strings.eqlComptime(arg, "-g") or strings.eqlComptime(arg, "--global"))) {
|
||||
break :brk .AddCommand;
|
||||
}
|
||||
}
|
||||
|
||||
break :brk .InstallCommand;
|
||||
},
|
||||
RootCommandMatcher.case("ci") => .InstallCommand,
|
||||
RootCommandMatcher.case("c"), RootCommandMatcher.case("create") => .CreateCommand,
|
||||
|
||||
RootCommandMatcher.case("test") => .TestCommand,
|
||||
|
||||
RootCommandMatcher.case("pm") => .PackageManagerCommand,
|
||||
|
||||
RootCommandMatcher.case("add"), RootCommandMatcher.case("a") => .AddCommand,
|
||||
|
||||
RootCommandMatcher.case("update") => .UpdateCommand,
|
||||
RootCommandMatcher.case("patch") => .PatchCommand,
|
||||
RootCommandMatcher.case("patch-commit") => .PatchCommitCommand,
|
||||
|
||||
RootCommandMatcher.case("r"),
|
||||
RootCommandMatcher.case("remove"),
|
||||
RootCommandMatcher.case("rm"),
|
||||
RootCommandMatcher.case("uninstall"),
|
||||
=> .RemoveCommand,
|
||||
|
||||
RootCommandMatcher.case("run") => .RunCommand,
|
||||
RootCommandMatcher.case("help") => .HelpCommand,
|
||||
|
||||
RootCommandMatcher.case("exec") => .ExecCommand,
|
||||
|
||||
RootCommandMatcher.case("outdated") => .OutdatedCommand,
|
||||
RootCommandMatcher.case("publish") => .PublishCommand,
|
||||
RootCommandMatcher.case("audit") => .AuditCommand,
|
||||
RootCommandMatcher.case("info") => .InfoCommand,
|
||||
|
||||
const RootCommandMap = bun.ComptimeStringMap(Command.Tag, .{
|
||||
.{ "init", .InitCommand },
|
||||
.{ "build", .BuildCommand },
|
||||
.{ "bun", .BuildCommand },
|
||||
.{ "discord", .DiscordCommand },
|
||||
.{ "upgrade", .UpgradeCommand },
|
||||
.{ "completions", .InstallCompletionsCommand },
|
||||
.{ "getcompletes", .GetCompletionsCommand },
|
||||
.{ "link", .LinkCommand },
|
||||
.{ "unlink", .UnlinkCommand },
|
||||
.{ "x", .BunxCommand },
|
||||
.{ "repl", .ReplCommand },
|
||||
.{ "ci", .InstallCommand },
|
||||
.{ "c", .CreateCommand },
|
||||
.{ "create", .CreateCommand },
|
||||
.{ "test", .TestCommand },
|
||||
.{ "pm", .PackageManagerCommand },
|
||||
.{ "add", .AddCommand },
|
||||
.{ "a", .AddCommand },
|
||||
.{ "update", .UpdateCommand },
|
||||
.{ "patch", .PatchCommand },
|
||||
.{ "patch-commit", .PatchCommitCommand },
|
||||
.{ "r", .RemoveCommand },
|
||||
.{ "remove", .RemoveCommand },
|
||||
.{ "rm", .RemoveCommand },
|
||||
.{ "uninstall", .RemoveCommand },
|
||||
.{ "run", .RunCommand },
|
||||
.{ "help", .HelpCommand },
|
||||
.{ "exec", .ExecCommand },
|
||||
.{ "outdated", .OutdatedCommand },
|
||||
.{ "publish", .PublishCommand },
|
||||
.{ "audit", .AuditCommand },
|
||||
.{ "info", .InfoCommand },
|
||||
// These are reserved for future use by Bun, so that someone
|
||||
// doing `bun deploy` to run a script doesn't accidentally break
|
||||
// when we add our actual command
|
||||
RootCommandMatcher.case("deploy") => .ReservedCommand,
|
||||
RootCommandMatcher.case("cloud") => .ReservedCommand,
|
||||
RootCommandMatcher.case("config") => .ReservedCommand,
|
||||
RootCommandMatcher.case("use") => .ReservedCommand,
|
||||
RootCommandMatcher.case("auth") => .ReservedCommand,
|
||||
RootCommandMatcher.case("login") => .ReservedCommand,
|
||||
RootCommandMatcher.case("logout") => .ReservedCommand,
|
||||
RootCommandMatcher.case("whoami") => .PackageManagerCommand,
|
||||
RootCommandMatcher.case("prune") => .ReservedCommand,
|
||||
RootCommandMatcher.case("list") => .ReservedCommand,
|
||||
RootCommandMatcher.case("why") => .WhyCommand,
|
||||
.{ "deploy", .ReservedCommand },
|
||||
.{ "cloud", .ReservedCommand },
|
||||
.{ "config", .ReservedCommand },
|
||||
.{ "use", .ReservedCommand },
|
||||
.{ "auth", .ReservedCommand },
|
||||
.{ "login", .ReservedCommand },
|
||||
.{ "logout", .ReservedCommand },
|
||||
.{ "whoami", .PackageManagerCommand },
|
||||
.{ "prune", .ReservedCommand },
|
||||
.{ "list", .ReservedCommand },
|
||||
.{ "why", .WhyCommand },
|
||||
.{ "-e", .AutoCommand },
|
||||
});
|
||||
|
||||
RootCommandMatcher.case("-e") => .AutoCommand,
|
||||
// Special case for install/i commands needing to check for global flag
|
||||
if (strings.eql(first_arg_name, "install") or strings.eql(first_arg_name, "i")) {
|
||||
for (args_iter.buf) |arg| {
|
||||
if (arg.len > 0 and (strings.eqlComptime(arg, "-g") or strings.eqlComptime(arg, "--global"))) {
|
||||
return .AddCommand;
|
||||
}
|
||||
}
|
||||
return .InstallCommand;
|
||||
}
|
||||
|
||||
else => .AutoCommand,
|
||||
};
|
||||
return RootCommandMap.get(first_arg_name) orelse .AutoCommand;
|
||||
}
|
||||
|
||||
const default_completions_list = [_]string{
|
||||
|
||||
@@ -876,7 +876,12 @@ pub fn parse(allocator: std.mem.Allocator, ctx: Command.Context, comptime cmd: C
|
||||
}
|
||||
}
|
||||
|
||||
const TargetMatcher = strings.ExactSizeMatcher(8);
|
||||
const TargetMap = bun.ComptimeStringMap(Api.Target, .{
|
||||
.{ "browser", Api.Target.browser },
|
||||
.{ "node", Api.Target.node },
|
||||
.{ "macro", if (cmd == .BuildCommand) Api.Target.bun_macro else Api.Target.bun },
|
||||
.{ "bun", Api.Target.bun },
|
||||
});
|
||||
if (args.option("--target")) |_target| brk: {
|
||||
if (comptime cmd == .BuildCommand) {
|
||||
if (args.flag("--compile")) {
|
||||
@@ -892,13 +897,7 @@ pub fn parse(allocator: std.mem.Allocator, ctx: Command.Context, comptime cmd: C
|
||||
}
|
||||
}
|
||||
|
||||
opts.target = opts.target orelse switch (TargetMatcher.match(_target)) {
|
||||
TargetMatcher.case("browser") => Api.Target.browser,
|
||||
TargetMatcher.case("node") => Api.Target.node,
|
||||
TargetMatcher.case("macro") => if (cmd == .BuildCommand) Api.Target.bun_macro else Api.Target.bun,
|
||||
TargetMatcher.case("bun") => Api.Target.bun,
|
||||
else => CLI.invalidTarget(&diag, _target),
|
||||
};
|
||||
opts.target = opts.target orelse TargetMap.get(_target) orelse CLI.invalidTarget(&diag, _target);
|
||||
|
||||
if (opts.target.? == .bun) {
|
||||
ctx.debug.run_in_bun = opts.target.? == .bun;
|
||||
|
||||
@@ -125,7 +125,12 @@ pub const Integrity = extern struct {
|
||||
}
|
||||
|
||||
pub fn parse(buf: []const u8) struct { Tag, usize } {
|
||||
const Matcher = strings.ExactSizeMatcher(8);
|
||||
const TagMap = bun.ComptimeStringMap(Tag, .{
|
||||
.{ "sha1", Tag.sha1 },
|
||||
.{ "sha256", Tag.sha256 },
|
||||
.{ "sha384", Tag.sha384 },
|
||||
.{ "sha512", Tag.sha512 },
|
||||
});
|
||||
|
||||
const i = strings.indexOfChar(buf[0..@min(buf.len, 7)], '-') orelse return .{ Tag.unknown, 0 };
|
||||
|
||||
@@ -133,13 +138,11 @@ pub const Integrity = extern struct {
|
||||
return .{ Tag.unknown, 0 };
|
||||
}
|
||||
|
||||
return switch (Matcher.match(buf[0..i])) {
|
||||
Matcher.case("sha1") => .{ Tag.sha1, i + 1 },
|
||||
Matcher.case("sha256") => .{ Tag.sha256, i + 1 },
|
||||
Matcher.case("sha384") => .{ Tag.sha384, i + 1 },
|
||||
Matcher.case("sha512") => .{ Tag.sha512, i + 1 },
|
||||
else => .{ Tag.unknown, 0 },
|
||||
};
|
||||
const tag = TagMap.get(buf[0..i]) orelse Tag.unknown;
|
||||
if (tag == Tag.unknown) {
|
||||
return .{ Tag.unknown, 0 };
|
||||
}
|
||||
return .{ tag, i + 1 };
|
||||
}
|
||||
|
||||
pub inline fn digestLen(this: Tag) usize {
|
||||
|
||||
@@ -1928,8 +1928,6 @@ pub fn moveSlice(slice: string, from: string, to: string) string {
|
||||
return result;
|
||||
}
|
||||
|
||||
pub const ExactSizeMatcher = @import("./immutable/exact_size_matcher.zig").ExactSizeMatcher;
|
||||
|
||||
pub const unicode_replacement = 0xFFFD;
|
||||
pub const unicode_replacement_str = brk: {
|
||||
var out: [std.unicode.utf8CodepointSequenceLength(unicode_replacement) catch unreachable]u8 = undefined;
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
pub fn ExactSizeMatcher(comptime max_bytes: usize) type {
|
||||
switch (max_bytes) {
|
||||
1, 2, 4, 8, 12, 16 => {},
|
||||
else => {
|
||||
@compileError("max_bytes must be 1, 2, 4, 8, 12, or 16.");
|
||||
},
|
||||
}
|
||||
|
||||
const T = std.meta.Int(
|
||||
.unsigned,
|
||||
max_bytes * 8,
|
||||
);
|
||||
|
||||
return struct {
|
||||
pub fn match(str: anytype) T {
|
||||
switch (str.len) {
|
||||
1...max_bytes - 1 => {
|
||||
var tmp: [max_bytes]u8 = undefined;
|
||||
@memcpy(tmp[0..str.len], str);
|
||||
@memset(tmp[str.len..], 0);
|
||||
|
||||
return std.mem.readInt(T, &tmp, .little);
|
||||
},
|
||||
max_bytes => {
|
||||
return std.mem.readInt(T, str[0..max_bytes], .little);
|
||||
},
|
||||
0 => {
|
||||
return 0;
|
||||
},
|
||||
else => {
|
||||
return std.math.maxInt(T);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn matchLower(str: anytype) T {
|
||||
switch (str.len) {
|
||||
1...max_bytes - 1 => {
|
||||
var tmp: [max_bytes]u8 = undefined;
|
||||
for (str, 0..) |char, i| {
|
||||
tmp[i] = std.ascii.toLower(char);
|
||||
}
|
||||
@memset(tmp[str.len..], 0);
|
||||
return std.mem.readInt(T, &tmp, .little);
|
||||
},
|
||||
max_bytes => {
|
||||
return std.mem.readInt(T, str[0..max_bytes], .little);
|
||||
},
|
||||
0 => {
|
||||
return 0;
|
||||
},
|
||||
else => {
|
||||
return std.math.maxInt(T);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn case(comptime str: []const u8) T {
|
||||
if (str.len < max_bytes) {
|
||||
var bytes = std.mem.zeroes([max_bytes]u8);
|
||||
bytes[0..str.len].* = str[0..str.len].*;
|
||||
return std.mem.readInt(T, &bytes, .little);
|
||||
} else if (str.len == max_bytes) {
|
||||
return std.mem.readInt(T, str[0..str.len], .little);
|
||||
} else {
|
||||
@compileError("str: \"" ++ str ++ "\" too long");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
Reference in New Issue
Block a user