magdalena

interactive shell navigation and history
Log | Files | Refs | README | LICENSE

io.zig (2069B)


      1 const std = @import("std");
      2 
      3 // Process-wide handles, populated once from `std.process.Init` in `main`. The
      4 // app is a short-lived single-threaded CLI, so threading these through every
      5 // call site would be pure noise; ambient state keeps the IO surface small.
      6 // They are optionals (not `undefined`) so that any use before `init` is a
      7 // checked unwrap panic rather than undefined behavior.
      8 var rt_handle: ?std.Io = null;
      9 var env_map: ?*std.process.Environ.Map = null;
     10 
     11 pub fn init(io_handle: std.Io, environ: *std.process.Environ.Map) void {
     12     rt_handle = io_handle;
     13     env_map = environ;
     14 }
     15 
     16 pub fn rt() std.Io {
     17     return rt_handle.?;
     18 }
     19 
     20 pub fn getenv(key: []const u8) ?[]const u8 {
     21     return env_map.?.get(key);
     22 }
     23 
     24 pub const Writer = struct {
     25     inner: std.Io.File.Writer,
     26     failed: bool = false,
     27 
     28     pub fn print(self: *Writer, comptime fmt: []const u8, args: anytype) !void {
     29         if (self.failed) return;
     30         self.inner.interface.print(fmt, args) catch |err| {
     31             if (err == error.WriteFailed) {
     32                 self.failed = true;
     33                 return;
     34             }
     35             return err;
     36         };
     37     }
     38 
     39     pub fn end(self: *Writer) !void {
     40         if (self.failed) return;
     41         self.inner.interface.flush() catch |err| {
     42             if (err == error.WriteFailed) {
     43                 self.failed = true;
     44                 return;
     45             }
     46             return err;
     47         };
     48     }
     49 };
     50 
     51 pub fn getStdout(buf: []u8) Writer {
     52     return .{ .inner = std.Io.File.stdout().writerStreaming(rt(), buf) };
     53 }
     54 
     55 pub fn warn(comptime fmt: []const u8, args: anytype) void {
     56     var buf: [4096]u8 = undefined;
     57     var writer = std.Io.File.stderr().writerStreaming(rt(), &buf);
     58     writer.interface.print(fmt, args) catch |err| {
     59         std.log.warn("failed to write to stderr: {}", .{err});
     60     };
     61     writer.interface.flush() catch |err| {
     62         std.log.warn("failed to flush stderr writer: {}", .{err});
     63     };
     64 }
     65 
     66 pub fn fatal(comptime fmt: []const u8, args: anytype) noreturn {
     67     warn(fmt ++ "\n", args);
     68     std.process.exit(1);
     69 }