Commit 220d3264c9

Veikka Tuominen <git@vexu.eu>
2024-01-27 23:30:24
std: make options a struct instance instead of a namespace
1 parent 776cd67
lib/std/log.zig
@@ -18,12 +18,12 @@
 //! ```
 //! const std = @import("std");
 //!
-//! pub const std_options = struct {
+//! pub const std_options = .{
 //!     // Set the log level to info
-//!     pub const log_level = .info;
+//!     .log_level = .info,
 //!
 //!     // Define logFn to override the std implementation
-//!     pub const logFn = myLogFn;
+//!     .logFn = myLogFn,
 //! };
 //!
 //! pub fn myLogFn(
lib/std/std.zig
@@ -195,79 +195,35 @@ pub const zig = @import("zig.zig");
 pub const start = @import("start.zig");
 
 const root = @import("root");
-const options_override = if (@hasDecl(root, "std_options")) root.std_options else struct {};
 
 /// Stdlib-wide options that can be overridden by the root file.
-pub const options = struct {
-    pub const enable_segfault_handler: bool = if (@hasDecl(options_override, "enable_segfault_handler"))
-        options_override.enable_segfault_handler
-    else
-        debug.default_enable_segfault_handler;
+pub const options: Options = if (@hasDecl(root, "std_options")) root.std_options else .{};
+
+pub const Options = struct {
+    enable_segfault_handler: bool = debug.default_enable_segfault_handler,
 
     /// Function used to implement `std.fs.cwd` for WASI.
-    pub const wasiCwd: fn () fs.Dir = if (@hasDecl(options_override, "wasiCwd"))
-        options_override.wasiCwd
-    else
-        fs.defaultWasiCwd;
-
-    /// The application's chosen I/O mode.
-    pub const io_mode: io.Mode = if (@hasDecl(options_override, "io_mode"))
-        options_override.io_mode
-    else if (@hasDecl(options_override, "event_loop"))
-        .evented
-    else
-        .blocking;
-
-    pub const event_loop: event.Loop.Instance = if (@hasDecl(options_override, "event_loop"))
-        options_override.event_loop
-    else
-        event.Loop.default_instance;
-
-    pub const event_loop_mode: event.Loop.Mode = if (@hasDecl(options_override, "event_loop_mode"))
-        options_override.event_loop_mode
-    else
-        event.Loop.default_mode;
+    wasiCwd: fn () fs.Dir = fs.defaultWasiCwd,
 
     /// The current log level.
-    pub const log_level: log.Level = if (@hasDecl(options_override, "log_level"))
-        options_override.log_level
-    else
-        log.default_level;
+    log_level: log.Level = log.default_level,
 
-    pub const log_scope_levels: []const log.ScopeLevel = if (@hasDecl(options_override, "log_scope_levels"))
-        options_override.log_scope_levels
-    else
-        &.{};
+    log_scope_levels: []const log.ScopeLevel = &.{},
 
-    pub const logFn: fn (
+    logFn: fn (
         comptime message_level: log.Level,
         comptime scope: @TypeOf(.enum_literal),
         comptime format: []const u8,
         args: anytype,
-    ) void = if (@hasDecl(options_override, "logFn"))
-        options_override.logFn
-    else
-        log.defaultLog;
-
-    pub const fmt_max_depth = if (@hasDecl(options_override, "fmt_max_depth"))
-        options_override.fmt_max_depth
-    else
-        fmt.default_max_depth;
-
-    pub const cryptoRandomSeed: fn (buffer: []u8) void = if (@hasDecl(options_override, "cryptoRandomSeed"))
-        options_override.cryptoRandomSeed
-    else
-        @import("crypto/tlcsprng.zig").defaultRandomSeed;
-
-    pub const crypto_always_getrandom: bool = if (@hasDecl(options_override, "crypto_always_getrandom"))
-        options_override.crypto_always_getrandom
-    else
-        false;
-
-    pub const crypto_fork_safety: bool = if (@hasDecl(options_override, "crypto_fork_safety"))
-        options_override.crypto_fork_safety
-    else
-        true;
+    ) void = log.defaultLog,
+
+    fmt_max_depth: usize = fmt.default_max_depth,
+
+    cryptoRandomSeed: fn (buffer: []u8) void = @import("crypto/tlcsprng.zig").defaultRandomSeed,
+
+    crypto_always_getrandom: bool = false,
+
+    crypto_fork_safety: bool = true,
 
     /// By default Zig disables SIGPIPE by setting a "no-op" handler for it.  Set this option
     /// to `true` to prevent that.
@@ -280,35 +236,22 @@ pub const options = struct {
     /// cases it's unclear why the process was terminated.  By capturing SIGPIPE instead, functions that
     /// write to broken pipes will return the EPIPE error (error.BrokenPipe) and the program can handle
     /// it like any other error.
-    pub const keep_sigpipe: bool = if (@hasDecl(options_override, "keep_sigpipe"))
-        options_override.keep_sigpipe
-    else
-        false;
+    keep_sigpipe: bool = false,
 
     /// By default, std.http.Client will support HTTPS connections.  Set this option to `true` to
     /// disable TLS support.
     ///
     /// This will likely reduce the size of the binary, but it will also make it impossible to
     /// make a HTTPS connection.
-    pub const http_disable_tls = if (@hasDecl(options_override, "http_disable_tls"))
-        options_override.http_disable_tls
-    else
-        false;
-
-    pub const side_channels_mitigations: crypto.SideChannelsMitigations = if (@hasDecl(options_override, "side_channels_mitigations"))
-        options_override.side_channels_mitigations
-    else
-        crypto.default_side_channels_mitigations;
+    http_disable_tls: bool = false,
+
+    side_channels_mitigations: crypto.SideChannelsMitigations = crypto.default_side_channels_mitigations,
 };
 
 // This forces the start.zig file to be imported, and the comptime logic inside that
 // file decides whether to export any appropriate start symbols, and call main.
 comptime {
     _ = start;
-
-    for (@typeInfo(options_override).Struct.decls) |decl| {
-        if (!@hasDecl(options, decl.name)) @compileError("no option named " ++ decl.name);
-    }
 }
 
 test {
lib/test_runner.zig
@@ -3,9 +3,9 @@ const std = @import("std");
 const io = std.io;
 const builtin = @import("builtin");
 
-pub const std_options = struct {
-    pub const io_mode: io.Mode = builtin.test_io_mode;
-    pub const logFn = log;
+pub const std_options = .{
+    .io_mode = builtin.test_io_mode,
+    .logFn = log,
 };
 
 var log_err_count: usize = 0;
src/main.zig
@@ -29,16 +29,16 @@ const AstGen = @import("AstGen.zig");
 const mingw = @import("mingw.zig");
 const Server = std.zig.Server;
 
-pub const std_options = struct {
-    pub const wasiCwd = wasi_cwd;
-    pub const logFn = log;
-    pub const enable_segfault_handler = false;
+pub const std_options = .{
+    .wasiCwd = wasi_cwd,
+    .logFn = log,
+    .enable_segfault_handler = false,
 
-    pub const log_level: std.log.Level = switch (builtin.mode) {
+    .log_level = switch (builtin.mode) {
         .Debug => .debug,
         .ReleaseSafe, .ReleaseFast => .info,
         .ReleaseSmall => .err,
-    };
+    },
 };
 
 // Crash report needs to override the panic handler
test/src/Cases.zig
@@ -1207,8 +1207,8 @@ const WaitGroup = std.Thread.WaitGroup;
 const build_options = @import("build_options");
 const Package = @import("../../src/Package.zig");
 
-pub const std_options = struct {
-    pub const log_level: std.log.Level = .err;
+pub const std_options = .{
+    .log_level = .err,
 };
 
 var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{
test/standalone/issue_9693/main.zig
@@ -1,4 +0,0 @@
-pub const std_options = struct {
-    pub const io_mode = .evented;
-};
-pub fn main() void {}
test/standalone/sigpipe/breakpipe.zig
@@ -1,11 +1,11 @@
 const std = @import("std");
 const build_options = @import("build_options");
 
-pub const std_options = if (build_options.keep_sigpipe) struct {
-    pub const keep_sigpipe = true;
-} else struct {
-    // intentionally not setting keep_sigpipe to ensure the default behavior is equivalent to false
-};
+pub usingnamespace if (build_options.keep_sigpipe) struct {
+    pub const std_options = .{
+        .keep_sigpipe = true,
+    };
+} else struct {};
 
 pub fn main() !void {
     const pipe = try std.os.pipe();
test/standalone/http.zig
@@ -7,8 +7,8 @@ const Client = http.Client;
 const mem = std.mem;
 const testing = std.testing;
 
-pub const std_options = struct {
-    pub const http_disable_tls = true;
+pub const std_options = .{
+    .http_disable_tls = true,
 };
 
 const max_header_size = 8192;
test/standalone/issue_7030.zig
@@ -1,7 +1,7 @@
 const std = @import("std");
 
-pub const std_options = struct {
-    pub const logFn = log;
+pub const std_options = .{
+    .logFn = log,
 };
 
 pub fn log(
test/compare_output.zig
@@ -440,14 +440,14 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
     cases.add("std.log per scope log level override",
         \\const std = @import("std");
         \\
-        \\pub const std_options = struct {
-        \\    pub const log_level: std.log.Level = .debug;
+        \\pub const std_options = .{
+        \\    .log_level = .debug,
         \\    
-        \\    pub const log_scope_levels = &[_]std.log.ScopeLevel{
+        \\    .log_scope_levels = &.{
         \\        .{ .scope = .a, .level = .warn },
         \\        .{ .scope = .c, .level = .err },
-        \\    };
-        \\    pub const logFn = log;
+        \\    },
+        \\    .logFn = log,
         \\};
         \\
         \\const loga = std.log.scoped(.a);
@@ -497,9 +497,9 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
     cases.add("std.heap.LoggingAllocator logs to std.log",
         \\const std = @import("std");
         \\
-        \\pub const std_options = struct {
-        \\    pub const log_level: std.log.Level = .debug;
-        \\    pub const logFn = log;
+        \\pub const std_options = .{
+        \\    .log_level = .debug,
+        \\    .logFn = log,
         \\};
         \\
         \\pub fn main() !void {