Skip to content

Basic Usage

Simple examples for compressing and extracting files.

Create Archive

zig
const std = @import("std");
const zigx = @import("zigx");

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    var result = try zigx.bundle(.{
        .allocator = allocator,
        .include = &.{ "src", "build.zig", "README.md" },
        .output_path = "bundle.zigx",
        .level = .best,
    });
    defer result.deinit();

    std.debug.print("Archive: {s}\n", .{result.output_path});
    std.debug.print("Files: {d}\n", .{result.file_count});
    std.debug.print("Size: {d} bytes\n", .{result.archive_size});
    std.debug.print("Saved: {d:.1}%\n", .{result.getCompressionPercent()});
}

Create Archive with Progress

zig
fn onProgress(info: zigx.ProgressInfo, ctx: ?*anyopaque) void {
    _ = ctx;
    switch (info.event) {
        .scanning => std.debug.print("Scanning...\n", .{}),
        .reading_file => {
            if (info.current_file) |file| {
                std.debug.print("\r[{d}/{d}] {s}", .{
                    info.files_processed, info.total_files, file,
                });
            }
        },
        .compressing => {
            std.debug.print("\rCompressing: {d:.1}%", .{info.getPercent()});
        },
        .finalizing => std.debug.print("\nFinalizing...", .{}),
        else => {},
    }
}

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    var result = try zigx.bundle(.{
        .allocator = allocator,
        .include = &.{ "src", "build.zig" },
        .output_path = "bundle.zigx",
        .level = .best,
        .progress_callback = onProgress,
    });
    defer result.deinit();

    std.debug.print("\nCreated: {s} ({d} bytes)\n", .{
        result.output_path, result.archive_size,
    });
}

Extract Archive

zig
pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    try zigx.unbundle(.{
        .archive_path = "bundle.zigx",
        .output_dir = "extracted",
        .allocator = allocator,
    });

    std.debug.print("Extraction complete.\n", .{});
}

Extract with Progress

zig
fn onExtractProgress(info: zigx.ExtractProgressInfo, ctx: ?*anyopaque) void {
    _ = ctx;
    switch (info.event) {
        .started => std.debug.print("Starting...\n", .{}),
        .extracting_file => {
            if (info.current_file) |file| {
                std.debug.print("\r[{d}/{d}] {s}", .{
                    info.files_extracted, info.total_files, file,
                });
            }
        },
        .completed => std.debug.print("\nDone!\n", .{}),
        else => {},
    }
}

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    try zigx.unbundle(.{
        .archive_path = "bundle.zigx",
        .output_dir = "extracted",
        .allocator = allocator,
        .progress_callback = onExtractProgress,
    });
}

List Files

zig
pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    const files = try zigx.list("bundle.zigx", allocator);
    defer {
        for (files) |f| allocator.free(f);
        allocator.free(files);
    }

    std.debug.print("Files in archive:\n", .{});
    for (files) |file| {
        std.debug.print("  {s}\n", .{file});
    }
}

Get Archive Info

zig
pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    var info = try zigx.getArchiveInfo("bundle.zigx", allocator);
    defer info.deinit();

    std.debug.print("Format Version: v{d}\n", .{info.format_version});
    std.debug.print("Compression Version: v{d}\n", .{info.compression_version});
    std.debug.print("File Count: {d}\n", .{info.file_count});
    std.debug.print("Original Size: {d} bytes\n", .{info.original_size});
    std.debug.print("Compressed Size: {d} bytes\n", .{info.compressed_size});
}

Validate Archive

zig
pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    // Quick check
    if (zigx.isValid("bundle.zigx")) {
        std.debug.print("Valid archive.\n", .{});
    }

    // Detailed validation
    const is_valid = try zigx.verify("bundle.zigx", allocator);
    if (is_valid) {
        std.debug.print("Archive integrity verified.\n", .{});
    }
}

Custom Compression Levels

zig
pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    // Using named levels
    _ = try zigx.bundle(.{
        .allocator = allocator,
        .include = &.{"src"},
        .output_path = "fast.zigx",
        .level = .fast,  // zstd level 1
    });

    // Using custom level (any value 1-22)
    _ = try zigx.bundle(.{
        .allocator = allocator,
        .include = &.{"src"},
        .output_path = "custom.zigx",
        .level = zigx.CompressionLevel.custom(15),  // zstd level 15
    });

    // Convert level to integer
    const level = zigx.CompressionLevel.best;
    const raw = level.toInt();  // Returns 19
    std.debug.print("Best level = {d}\n", .{raw});
}

Using OptionsBuilder

zig
fn onProgress(info: zigx.ProgressInfo, ctx: ?*anyopaque) void {
    _ = ctx;
    if (info.current_file) |file| {
        std.debug.print("\r[{d}/{d}] {s}", .{
            info.files_processed, info.total_files, file,
        });
    }
}

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    var builder = zigx.OptionsBuilder.init(allocator);
    const opts = builder
        .include(&.{ "src", "build.zig" })
        .exclude(&.{ "*.tmp", "zig-cache" })
        .outputPath("project.zigx")
        .ultra()  // Maximum compression (level 22)
        .progress(onProgress, null)
        .build();

    var result = try zigx.bundle(opts);
    defer result.deinit();
}

Using ConfigBuilder

zig
pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    // Build a custom configuration
    var cfgBuilder = zigx.ConfigBuilder.init();
    const cfg = cfgBuilder
        .compressionLevel(.best)
        .adaptive(true)
        .longDistanceMatching(true)
        .verbose(true)
        .build();

    // Use configuration with bundle options
    const opts = zigx.CompressOptions.fromConfig(cfg, allocator);
    // Then set include/output_path manually or use OptionsBuilder
}

Error Handling

zig
const result = zigx.bundle(.{
    .allocator = allocator,
    .include = &.{"nonexistent"},
    .output_path = "out.zigx",
}) catch |err| {
    switch (err) {
        error.FileNotFound => std.debug.print("File not found.\n", .{}),
        error.NoFilesSpecified => std.debug.print("No files to bundle.\n", .{}),
        else => std.debug.print("Error: {}\n", .{err}),
    }
    return;
};
defer result.deinit();

Released under the Apache License 2.0.