### Complete Zig Build Example with Standard Options Source: https://www.zigbook.net/chapters/22__build-system-deep-dive A comprehensive `build.zig` example demonstrating the integration of `b.standardTargetOptions` and `b.standardOptimizeOption` to create a configurable executable. It sets up the target and optimization, adds the executable, and configures a run step. ```zig const std = @import("std"); // Demonstrating standardTargetOptions and standardOptimizeOption pub fn build(b: *std.Build) void { // Allows user to choose target: zig build -Dtarget=x86_64-linux const target = b.standardTargetOptions(.{}); // Allows user to choose optimization: zig build -Doptimize=ReleaseFast const optimize = b.standardOptimizeOption(.{}); const exe = b.addExecutable(.{ .name = "configurable", .root_module = b.createModule(.{ .root_source_file = b.path("main.zig"), .target = target, .optimize = optimize, }), }); b.installArtifact(exe); // Add run step const run_cmd = b.addRunArtifact(exe); run_cmd.step.dependOn(b.getInstallStep()); const run_step = b.step("run", "Run the application"); run_step.dependOn(&run_cmd.step); } ``` -------------------------------- ### Shell: Execute Zig Defer Example Source: https://www.zigbook.net/chapters/04__errors-resource-cleanup Command to compile and run the Zig code example demonstrating `defer` for resource management. Shows the output when jobs succeed and fail. ```shell $ zig run defer_cleanup.zig ``` -------------------------------- ### Minimal Zig Build Script (build.zig) Source: https://www.zigbook.net/chapters/22__build-system-deep-dive This is the most basic `build.zig` file. It defines a single executable named 'hello' and installs it to the output directory. It hard-codes the target to the host machine and the optimization level to Debug, serving as a foundational example for Zig's build system. ```zig const std = @import("std"); // Minimal build.zig: single executable, no options // Demonstrates the simplest possible build script for the Zig build system. pub fn build(b: *std.Build) void { // Create an executable compilation step with minimal configuration. // This represents the fundamental pattern for producing a binary artifact. const exe = b.addExecutable(.{ // The output binary name (becomes "hello" or "hello.exe") .name = "hello", // Configure the root module with source file and compilation settings .root_module = b.createModule(.{ // Specify the entry point source file relative to build.zig .root_source_file = b.path("main.zig"), // Target the host machine (the system running the build) .target = b.graph.host, // Use Debug optimization level (no optimizations, debug symbols included) .optimize = .Debug, }), }); // Register the executable to be installed to the output directory. // When `zig build` runs, this artifact will be copied to zig-out/bin/ b.installArtifact(exe); } ``` -------------------------------- ### Run Zig code example Source: https://www.zigbook.net/chapters/46__io-and-stream-adapters This section shows the command to execute the Zig code snippet provided previously. It assumes the code is saved in a file named `stream_pipeline.zig`. ```Shell $ zig run stream_pipeline.zig ``` -------------------------------- ### Directory Walker Output Example Source: https://www.zigbook.net/chapters/28__filesystem-and-io Demonstrates the output of a Zig directory walker program, showing the types of entries (DIR/FILE), their paths, sizes, and file types. It also provides a summary of directories and files found. ```Shell DIR logs DIR logs/jobs FILE logs/jobs/batch.log (8 bytes) [log] DIR logs/app FILE logs/app/errors.log (9 bytes) [log] FILE logs/app/today.log (7 bytes) [log] DIR notes FILE notes/todo.txt (12 bytes) --- summary --- directories: 4 files: 4 log files: 3 ``` -------------------------------- ### Zig: Define Sample Files for Archiving Source: https://www.zigbook.net/chapters/54__project-zip-unzip-with-progress Defines a structure `SampleFile` to hold file paths and contents, and initializes an array `sample_files` with example data for archiving. This includes text, JSON, and log files. ```zig const SampleFile = struct { path: []const u8, contents: []const u8, }; const sample_files = [_]SampleFile{ .{ .path = "input/metrics.txt", .contents = "uptime=420s\nrequests=1312\nerrors=3\n" }, .{ .path = "input/inventory.json", .contents = "{\n \"service\": \"telemetry\",\n \"shards\": [\"alpha\", \"beta\", \"gamma\"]\n}\n" }, .{ .path = "input/logs/app.log", .contents = "[info] ingest started\n[warn] queue delay=87ms\n[info] ingest completed\n" }, .{ .path = "input/README.md", .contents = "# Telemetry bundle\n\nSynthetic records used for the zip/unzip progress demo.\n" }, }; ``` -------------------------------- ### Zig Build and Run Command Source: https://www.zigbook.net/chapters/01__boot-basics This shell command demonstrates how to compile and run a Zig program named 'values_and_literals.zig' using the Zig compiler. It assumes the Zig toolchain is installed and accessible in the system's PATH. ```shell $ zig run values_and_literals.zig ``` -------------------------------- ### Verify Zig Installation Source: https://www.zigbook.net/chapters/00__zigbook_introduction This command checks if the Zig toolchain is installed and accessible in the system's PATH. It's a crucial first step to ensure the correct version is being used, especially when following along with examples that rely on specific version behaviors. ```shell $ zig version 0.15.X ``` -------------------------------- ### Main Function: HTTP Client and Server Setup (Zig) Source: https://www.zigbook.net/chapters/32__project-http-json-client The main function sets up a general-purpose allocator, binds a server to localhost, and spawns a server thread. It then initializes an HTTP client, creates an arena allocator for parsed data, constructs the request URL, fetches the status, and finally renders the summary. ```zig pub fn main() !void { // Set up a general-purpose allocator for long-lived allocations (client, server). var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); const allocator = gpa.allocator(); // Bind to localhost on an OS-assigned port (port 0 → automatic selection). const address = try std.net.Address.parseIp("127.0.0.1", 0); var server = try address.listen(.{ .reuse_address = true }); defer server.deinit(); // Spin up the server fixture on a background thread. var ready = std.Thread.ResetEvent{}; const server_thread = try std.Thread.spawn(.{}, serveStatus, .{ServerTask{ .server = &server, .ready = &ready, }}); defer server_thread.join(); // Wait for the server thread to signal that it's ready to accept connections. ready.wait(); // Retrieve the actual port chosen by the OS. const port = server.listen_address.in.getPort(); // Initialize the HTTP client with the main allocator. var client = std.http.Client{ .allocator = allocator }; defer client.deinit(); // Create an arena allocator for all parsed data. // The arena owns all slices in the Summary; they're freed when the arena is destroyed. var arena_inst = std.heap.ArenaAllocator.init(allocator); defer arena_inst.deinit(); const arena = arena_inst.allocator(); // Set up buffered stdout for logging. var stdout_buffer: [256]u8 = undefined; var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); const log_out = &stdout_writer.interface; // Construct the full URL with the dynamically assigned port. var url_buffer: [128]u8 = undefined; const url = try std.fmt.bufPrint(&url_buffer, "http://127.0.0.1:{d}/api/status", .{port}); try log_out.print("Fetching {s}...\n", .{url}); // Fetch and decode the status endpoint. const summary = try fetchSummary(arena, &client, url); try log_out.print("Parsed {d} regions.\n\n", .{summary.regions.len}); try log_out.flush(); // Render the final report to stdout. try renderSummary(summary); } ``` -------------------------------- ### Zig Test Execution Source: https://www.zigbook.net/chapters/55__style-guide-highlights Command to execute tests for a Zig file, demonstrating how to run the tests defined within the module layout example. ```shell $ zig test 03_module_layout.zig ``` -------------------------------- ### Zig Package Overlay Demo: Main Function Source: https://www.zigbook.net/chapters/20__concept-primer-modules-vs-programs-vs-packages-vs-libraries This Zig code demonstrates how to register and display package information using the overlay library. It imports necessary modules, sets up stdout for writing, populates package details including build mode and target OS, and renders a summary. Dependencies include the standard library and the 'overlay' module. ```zig const std = @import("std"); const builtin = @import("builtin"); const overlay = @import("overlay"); /// Entry point for the package overlay demonstration program. /// Demonstrates how to use the overlay_widget library to display package information /// including build mode and target operating system details. pub fn main() !void { var stdout_buffer: [512]u8 = undefined; var file_writer = std.fs.File.stdout().writer(&stdout_buffer); const stdout = &file_writer.interface; const details = overlay.PackageDetails{ .package_name = "overlay", .role = "library package", .optimize_mode = @tagName(builtin.mode), .target_os = @tagName(builtin.target.os.tag), }; try overlay.renderSummary(stdout, details); try stdout.flush(); } ``` -------------------------------- ### Run Zig Child Process Capture Example Source: https://www.zigbook.net/chapters/48__process-and-environment This shell command demonstrates how to compile and run the Zig code designed to capture child process output. It assumes the Zig compiler is installed and the source file is named `child_process_capture.zig`. ```shell $ zig run child_process_capture.zig ``` -------------------------------- ### Minimal Zig Program (main.zig) Source: https://www.zigbook.net/chapters/22__build-system-deep-dive This is the entry point for the minimal Zig build example. It contains a simple `main` function that prints a greeting to the console, demonstrating a basic Zig program structure that can be compiled and run using the Zig build system. ```zig // Entry point for a minimal Zig build system example. // This demonstrates the simplest possible Zig program structure that can be built // using the Zig build system, showing the basic main function and standard library import. const std = @import("std"); pub fn main() !void { std.debug.print("Hello from minimal build!\n", .{}); } ``` -------------------------------- ### Zig: Tight Error Vocabularies for Numeric Parsing Source: https://www.zigbook.net/chapters/55__style-guide-highlights Illustrates how to maintain tight error vocabularies in Zig for a numeric parser. This allows callers to react precisely to specific failure modes instead of a generic `anyerror`. The example defines a custom error set and a parsing function. ```Zig //! Keeps error vocabulary tight for a numeric parser so callers can react precisely. const std = @import("std"); /// Enumerates the failure modes that the parser can surface to its callers. pub const ParseCountError = error{ EmptyInput, InvalidDigit, Overflow, }; /// Parses a decimal counter while preserving descriptive error information. pub fn parseCount(input: []const u8) ParseCountError!u32 { if (input.len == 0) return ParseCountError.EmptyInput; var acc: u64 = 0; for (input) |char| { if (char < '0' or char > '9') return ParseCountError.InvalidDigit; const digit: u64 = @intCast(char - '0'); acc = acc * 10 + digit; if (acc > std.math.maxInt(u32)) return ParseCountError.Overflow; } return @intCast(acc); } test "parseCount reports invalid digits precisely" { try std.testing.expectEqual(@as(u32, 42), try parseCount("42")); try std.testing.expectError(ParseCountError.InvalidDigit, parseCount("4a")); try std.testing.expectError(ParseCountError.EmptyInput, parseCount("")); try std.testing.expectError(ParseCountError.Overflow, parseCount("42949672960")); } ``` -------------------------------- ### Scaffold Zig Project with Minimal Template Source: https://www.zigbook.net/chapters/21__zig-init-and-package-metadata Shows how to use `zig init --minimal` to create a Zig project with the least amount of boilerplate. This is useful for experienced users and generates only `build.zig.zon` and a stub `build.zig`. ```shell mkdir minimal-project && cd minimal-project zig init --minimal ``` -------------------------------- ### Zig Module Layout: Retry Policy Example Source: https://www.zigbook.net/chapters/55__style-guide-highlights Demonstrates a layered module layout in Zig, defining a RetryPolicy struct with default values, helper functions like isBackoffEnabled, and functions to create and validate retry policies. Includes tests for error handling and default policy acceptance. ```zig //! Highlights a layered module layout with focused helper functions and tests. const std = @import("std"); /// Errors that can emerge while normalizing user-provided retry policies. pub const RetryPolicyError = error{ ZeroAttempts, ExcessiveDelay, }; /// Encapsulates retry behaviour for a network client, including sensible defaults. pub const RetryPolicy = struct { max_attempts: u8 = 3, delay_ms: u32 = 100, /// Indicates whether exponential backoff is active. pub fn isBackoffEnabled(self: RetryPolicy) bool { return self.delay_ms > 0 and self.max_attempts > 1; } }; /// Partial options provided by configuration files or CLI flags. pub const PartialRetryOptions = struct { max_attempts: ?u8 = null, delay_ms: ?u32 = null, }; /// Builds a retry policy from optional overrides while keeping default reasoning centralized. pub fn makeRetryPolicy(options: PartialRetryOptions) RetryPolicy { return RetryPolicy{ .max_attempts = options.max_attempts orelse 3, .delay_ms = options.delay_ms orelse 100, }; } fn validate(policy: RetryPolicy) RetryPolicyError!RetryPolicy { if (policy.max_attempts == 0) return RetryPolicyError.ZeroAttempts; if (policy.delay_ms > 60_000) return RetryPolicyError.ExcessiveDelay; return policy; } /// Produces a validated policy, emphasising the flow from raw input to constrained output. pub fn finalizeRetryPolicy(options: PartialRetryOptions) RetryPolicyError!RetryPolicy { const policy = makeRetryPolicy(options); return validate(policy); } test "finalize rejects zero attempts" { try std.testing.expectError( RetryPolicyError.ZeroAttempts, finalizeRetryPolicy(.{ .max_attempts = 0 }), ); } test "finalize accepts defaults" { const policy = try finalizeRetryPolicy(.{}); try std.testing.expectEqual(@as(u8, 3), policy.max_attempts); try std.testing.expect(policy.isBackoffEnabled()); } ``` -------------------------------- ### Shell: Output of Zig Defer Example Source: https://www.zigbook.net/chapters/04__errors-resource-cleanup The execution output of the Zig `defer` example, illustrating resource acquisition, work, success/failure messages, and the guaranteed release of resources. ```shell -- cycle alpha -- acquiring alpha working with alpha job alpha succeeded release alpha -- cycle beta -- acquiring beta working with beta job beta failed release beta beta bubbled up CalibrateFailed ``` -------------------------------- ### Zig: Main Function Setup for Memory Allocation and Testing Source: https://www.zigbook.net/chapters/54__project-zip-unzip-with-progress This Zig code snippet sets up the main execution environment. It initializes a general-purpose allocator, defers its deinitialization to check for memory leaks, and obtains a standard allocator instance. It also sets up a buffered writer for standard output and creates a temporary directory for testing, ensuring cleanup afterwards. ```zig pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer { const leak_status = gpa.deinit(); std.debug.assert(leak_status == .ok); } const allocator = gpa.allocator(); var stdout_buffer: [512]u8 = undefined; var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); const out = &stdout_writer.interface; var tmp = std.testing.tmpDir(.{}); defer tmp.cleanup(); var metrics = std.StringHashMap(EntryMetrics).init(allocator); defer { var it = metrics.iterator(); while (it.next()) |kv| { allocator.free(kv.key_ptr.*); } metrics.deinit(); } var progress_root = std.Progress.start(.{ .root_name = "zip-pipeline", .estimated_total_items = 3, .disable_printing = true, }); } ``` -------------------------------- ### Zig Hello World Program Source: https://www.zigbook.net/chapters/00__zigbook_introduction The foundational 'Hello, world!' program in Zig. It demonstrates basic program structure, importing the standard library, defining the main function, and using `std.debug.print` for output. This is a simple way to verify the compiler and standard library are functioning correctly. ```zig const std = @import("std"); pub fn main() void { std.debug.print("Hello, world!\n", .{}); } ``` -------------------------------- ### Basic std.Progress Usage Example Source: https://www.zigbook.net/chapters/47__time-logging-and-progress Demonstrates the fundamental usage of `std.Progress` to report the progress of tasks. It initializes a root task and then child tasks like 'compile' and 'link', marking them as complete. Printing is disabled for deterministic output in this example. ```zig const std = @import("std"); pub fn main() void { // Progress can draw to stderr; disable printing in this demo for deterministic output. const root = std.Progress.start(.{ .root_name = "build", .estimated_total_items = 3, .disable_printing = true }); var compile = root.start("compile", 2); compile.completeOne(); compile.completeOne(); compile.end(); var link = root.start("link", 1); link.completeOne(); link.end(); root.end(); } ``` -------------------------------- ### Shell Command: Build and Run Zig Package Overlay Demo Source: https://www.zigbook.net/chapters/20__concept-primer-modules-vs-programs-vs-packages-vs-libraries This shell command compiles a Zig executable named 'overlay_demo' and then runs it. It utilizes the `-M` and `--dep` flags to register and import modules, specifically defining the root module and the 'overlay' module. The output shows the registered package information. ```shell $ zig build-exe --dep overlay -Mroot=package_overlay_demo.zig -Moverlay=overlay_widget.zig -femit-bin=overlay_demo && ./overlay_demo ``` -------------------------------- ### Zig: Modules, Imports, and Buffered I/O Source: https://www.zigbook.net/chapters/01__boot-basics This Zig code demonstrates importing modules (`std`, `builtin`, `root`) and accessing their public declarations. It shows how to use buffered stdout for efficient output and dynamically print build information such as application name, optimization mode, and target architecture. Requires Zig compiler. ```zig // File: chapters-data/code/01__boot-basics/imports.zig // Import the standard library for I/O, memory management, and core utilities const std = @import("std"); // Import builtin to access compile-time information about the build environment const builtin = @import("builtin"); // Import root to access declarations from the root source file // In this case, we reference app_name which is defined in this file const root = @import("root"); // Public constant that can be accessed by other modules importing this file pub const app_name = "Boot Basics Tour"; // Main entry point of the program // Returns an error union to propagate any I/O errors during execution pub fn main() !void { // Allocate a fixed-size buffer on the stack for stdout operations // This buffer batches write operations to reduce syscalls var stdout_buffer: [256]u8 = undefined; // Create a buffered writer wrapping stdout var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); // Get the generic writer interface for polymorphic I/O operations const stdout = &stdout_writer.interface; // Print the application name by referencing the root module's declaration // Demonstrates how @import("root") allows access to the entry file's public declarations try stdout.print("app: {s}\n", .{root.app_name}); // Print the optimization mode (Debug, ReleaseSafe, ReleaseFast, or ReleaseSmall) // @tagName converts the enum value to its string representation try stdout.print("optimize mode: {s}\n", .{@tagName(builtin.mode)}); // Print the target triple showing CPU architecture, OS, and ABI // Each component is extracted from builtin.target and converted to a string try stdout.print( "target: {s}-{s}-{s}\n", { @tagName(builtin.target.cpu.arch), @tagName(builtin.target.os.tag), @tagName(builtin.target.abi), }, ); // Flush the buffer to ensure all accumulated output is written to stdout try stdout.flush(); } ``` -------------------------------- ### Zig Atomic Initialization Example Source: https://www.zigbook.net/chapters/29__threads-and-atomics Demonstrates using Zig's atomic compare-and-swap (`@cmpxchgStrong`) for thread-safe initialization, ensuring a function is called exactly once. It prints the number of initialization calls and the final configuration value. The example uses `.release` semantics for the final store to ensure visibility. ```zig const std = @import("std"); const atomic = std.atomic; const out = std.io.getStdOut().writer(); var called: u64 = 0; var final_value: u64 = 0; fn init() void { final_value = atomic.cmpxchgStrong( @ptrCast(u64, &called), 0, 1, .unordered, .unordered, ); if (final_value == 0) { // Actual initialization logic here std.time.sleep(1000 * 1000); final_value = 9157; // Example value atomic.store(&final_value, 1, .monotonic); } else { // Another thread already initialized, load the value final_value = atomic.load(&final_value, .monotonic); } } pub fn main() !void { var threads = std.Thread.ChainedScheduler.init(.{}); defer threads.deinit(); var i: u32 = 0; while (i < 4) { threads.spawn(init) catch @panic("failed to spawn thread"); i += 1; } threads.join(); // Verify initialization was called exactly once try out.print("init calls: {d}\n", .{called}); // Display the final configuration value try out.print("config value: {d}\n", .{final_value}); try out.flush(); } ``` -------------------------------- ### Zig Values, Literals, and Debug Printing Example Source: https://www.zigbook.net/chapters/01__boot-basics This Zig code snippet demonstrates declaring variables and constants of various types, including integers, floats, booleans, and characters. It also shows how to use `std.debug.print` for output, including compile-time type reflection using `@TypeOf` and `@typeName`. This example is suitable for development and debugging. ```zig // File: chapters-data/code/01__boot-basics/values_and_literals.zig const std = @import("std"); pub fn main() !void { // Declare a mutable variable with explicit type annotation // u32 is an unsigned 32-bit integer, initialized to 1 var counter: u32 = 1; // Declare an immutable constant with inferred type (comptime_int) // The compiler infers the type from the literal value 2 const increment = 2; // Declare a constant with explicit floating-point type // f64 is a 64-bit floating-point number const ratio: f64 = 0.5; // Boolean constant with inferred type // Demonstrates Zig's type inference for simple literals const flag = true; // Character literal representing a newline // Single-byte characters are u8 values in Zig const newline: u8 = '\n'; // The unit type value, analogous to () in other languages // Represents "no value" or "nothing" explicitly const unit_value = void{}; // Mutate the counter by adding the increment // Only var declarations can be modified counter += increment; // Print formatted output showing different value types // {} is a generic format specifier that works with any type std.debug.print("counter={} ratio={} safety={}\n", .{ counter, ratio, flag }); // Cast the newline byte to u32 for display as its ASCII decimal value // @as performs explicit type coercion std.debug.print("newline byte={} (ASCII)\n", .{@as(u32, newline)}); // Use compile-time reflection to print the type name of unit_value // @TypeOf gets the type, @typeName converts it to a string std.debug.print("unit literal has type {s}\n", .{@typeName(@TypeOf(unit_value))}); } ``` -------------------------------- ### Zig Build Workspace Modules and Executable Source: https://www.zigbook.net/chapters/26__build-system-advanced-topics This Zig code defines a build process for a workspace consisting of multiple modules (analytics, reporting, adapters) and a root executable. It demonstrates module registration, dependency management, and artifact installation. Key functions include `b.addModule`, `b.createModule`, `b.addExecutable`, and `b.installArtifact`. ```zig const std = @import("std"); pub fn build(b: *std.Build) void { // Standard target and optimization options allow the build to be configured // for different architectures and optimization levels via CLI flags const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); // Create the analytics module - the foundational module that provides // core metric calculation and analysis capabilities const analytics_mod = b.addModule("analytics", .{ .root_source_file = b.path("workspace/analytics/lib.zig"), .target = target, .optimize = optimize, }); // Create the reporting module - depends on analytics to format and display metrics // Uses addModule() which both creates and registers the module in one step const reporting_mod = b.addModule("reporting", .{ .root_source_file = b.path("workspace/reporting/lib.zig"), .target = target, .optimize = optimize, // Import analytics module to access metric types and computation functions .imports = &.{.{ .name = "analytics", .module = analytics_mod }}, }); // Create the adapters module using createModule() - creates but does not register // This demonstrates an anonymous module that other code can import but won't // appear in the global module namespace const adapters_mod = b.createModule(.{ .root_source_file = b.path("workspace/adapters/vendored.zig"), .target = target, .optimize = optimize, // Adapters need analytics to serialize metric data .imports = &.{.{ .name = "analytics", .module = analytics_mod }}, }); // Create the main application module that orchestrates all dependencies // This demonstrates how a root module can compose multiple imported modules const app_module = b.createModule(.{ .root_source_file = b.path("workspace/app/main.zig"), .target = target, .optimize = optimize, .imports = &.{ // Import all three workspace modules to access their functionality .{ .name = "analytics", .module = analytics_mod }, .{ .name = "reporting", .module = reporting_mod }, .{ .name = "adapters", .module = adapters_mod }, }, }); // Create the executable artifact using the composed app module as its root // The root_module field replaces the legacy root_source_file approach const exe = b.addExecutable(.{ .name = "workspace-app", .root_module = app_module, }); // Install the executable to zig-out/bin so it can be run after building b.installArtifact(exe); // Set up a run command that executes the built executable const run_cmd = b.addRunArtifact(exe); // Forward any command-line arguments passed to the build system to the executable if (b.args) |args| { run_cmd.addArgs(args); } // Create a custom build step "run" that users can invoke with `zig build run` const run_step = b.step("run", "Run workspace app with registered modules"); run_step.dependOn(&run_cmd.step); // Create a named write files step to document the module dependency graph // This is useful for understanding the workspace structure without reading code const graph_files = b.addNamedWriteFiles("graph"); // Generate a text file documenting the module registration hierarchy _ = graph_files.add("module-graph.txt", \workspace module registration map: \ analytics -> workspace/analytics/lib.zig \ reporting -> workspace/reporting/lib.zig (imports analytics) \ adapters -> (anonymous) workspace/adapters/vendored.zig \ exe root -> workspace/app/main.zig ); // Create a custom build step "graph" that generates module documentation // Users can invoke this with `zig build graph` to output the dependency map const graph_step = b.step("graph", "Emit module graph summary to zig-out"); graph_step.dependOn(&graph_files.step); } ``` -------------------------------- ### Zig Tagged and Untagged Unions Example Source: https://www.zigbook.net/chapters/08__user-types-structs-enums-unions Demonstrates the usage of tagged unions with enum discriminants for type safety and untagged unions for low-level bit reinterpretations. Includes functions for printing union values and examples of compile-time checks. Dependencies: Zig standard library. ```zig const std = @import("std"); // Chapter 8 — Unions: tagged and untagged // // Demonstrates a tagged union (with enum discriminant) and an untagged union // (without discriminant). Tagged unions are safe and idiomatic; untagged // unions are advanced and unsafe if used incorrectly. // // Usage: // zig run union_demo.zig const Kind = enum { number, text }; const Value = union(Kind) { number: i64, text: []const u8, }; // Untagged union (advanced): requires external tracking and is unsafe if used wrong. const Raw = union { u: u32, i: i32 }; pub fn main() !void { var v: Value = .{ .number = 42 }; printValue("start: ", v); v = .{ .text = "hi" }; printValue("update: ", v); // Untagged example: write as u32, read as i32 (bit reinterpret). const r = Raw{ .u = 0xFFFF_FFFE }; // -2 as signed 32-bit const as_i: i32 = @bitCast(r.u); std.debug.print("raw u=0x{X:0>8} i={d}\n", .{ r.u, as_i }); } fn printValue(prefix: []const u8, v: Value) void { switch (v) { .number => |n| std.debug.print("{s}number={d}\n", .{ prefix, n }), .text => |s| std.debug.print("{s}{s}\n", .{ prefix, s }), } } ``` -------------------------------- ### HTTP GET Request and JSON Parsing in Zig Source: https://www.zigbook.net/chapters/31__networking-http-and-json Performs an HTTP GET request, writes the response to a fixed buffer, parses the JSON response into a predefined struct, and prints selected fields. It uses `std.Io.Writer.fixed` for the response buffer and `std.json.parseFromSlice` for parsing. Errors are handled using `try`, and memory allocated for JSON parsing is freed using `defer parsed.deinit()`. ```zig // Allocate buffer to receive the HTTP response body var response_buffer: [512]u8 = undefined; // Create a fixed-size writer that will capture the response var response_writer = std.Io.Writer.fixed(response_buffer[0..]); // Perform the HTTP GET request with custom User-Agent header const fetch_result = try client.fetch(.{ .location = .{ .url = url }, .response_writer = &response_writer, // Where to write response body .headers = .{ .user_agent = .{ .override = "zigbook-demo/0.15.2" }, }, }); // Get the slice containing the actual response body bytes const body = std.Io.Writer.buffered(&response_writer); // Define the expected structure of the JSON response const ResponseShape = struct { service: []const u8, message: []const u8, method: []const u8, path: []const u8, sequence: u32, }; // Parse the JSON response into a typed struct var parsed = try std.json.parseFromSlice(ResponseShape, allocator, body, .{}); // Free the memory allocated during JSON parsing defer parsed.deinit(); // Set up a buffered writer for stdout to efficiently output results var stdout_storage: [256]u8 = undefined; var stdout_state = std.fs.File.stdout().writer(&stdout_storage); const out = &stdout_state.interface; // Display the HTTP response status code try out.print("status: {d}\n", .{@intFromEnum(fetch_result.status)}); // Display the parsed JSON fields try out.print("service: {s}\n", .{parsed.value.service}); try out.print("method: {s}\n", .{parsed.value.method}); try out.print("path: {s}\n", .{parsed.value.path}); try out.print("message: {s}\n", .{parsed.value.message}); // Ensure all output is visible before program exits try out.flush(); ``` -------------------------------- ### Run Zig Allocator Fallback Example Source: https://www.zigbook.net/chapters/11__project-dynamic-string-builder This command executes the Zig program designed to demonstrate the `stackFallback` allocator. It compiles and runs the `allocator_fallback.zig` file, producing output that shows the behavior of stack and arena allocations. ```shell $ zig run allocator_fallback.zig ``` -------------------------------- ### Zig Struct Forwarding: Build Report Example Source: https://www.zigbook.net/chapters/60__advanced-result-location-semantics Demonstrates how struct literals in Zig forward result locations to each field, enabling direct writes without temporary copies. This example builds a statistics report, summarizing sensor readings into a 'Report' struct, including min/max range and bucket counts for a histogram. It utilizes nested literals and demonstrates transitive inheritance of result locations. ```Zig //! Builds a statistics report using struct literals that forward into the caller's result location. const std = @import("std"); pub const Report = struct { range: struct { min: u8, max: u8, }, buckets: [4]u32, }; pub fn buildReport(values: []const u8) Report { var histogram = [4]u32{ 0, 0, 0, 0 }; if (values.len == 0) { return .{ .range = .{ .min = 0, .max = 0 }, .buckets = histogram, }; } var current_min: u8 = std.math.maxInt(u8); var current_max: u8 = 0; for (values) |value| { current_min = @min(current_min, value); current_max = @max(current_max, value); const bucket_index = value / 64; histogram[bucket_index] += 1; } return .{ .range = .{ .min = current_min, .max = current_max }, .buckets = histogram, }; } test "buildReport summarises range and bucket counts" { const data = [_]u8{ 3, 19, 64, 129, 200 }; const report = buildReport(&data); try std.testing.expectEqual(@as(u8, 3), report.range.min); try std.testing.expectEqual(@as(u8, 200), report.range.max); try std.testing.expectEqualSlices(u32, &[_]u32{ 2, 1, 1, 1 }, &report.buckets); } ```