---
source: tests/backends_zig_snapshot_test.rs
assertion_line: 201
expression: "&file.content"
---
// Generated by alef. Do not edit by hand.

const std = @import("std");
pub const c = @cImport(@cInclude("demo.h"));

/// Free a string allocated by the FFI layer.
/// Free a string allocated by the FFI layer.
/// The pointer must have been returned by a `demo_*` C function.
/// Do NOT call this twice on the same pointer.
pub fn _free_string(ptr: [*c]u8) void {
    c.demo_free_string(ptr);
}

/// Retrieve the last error set by the FFI layer, if any.
/// Returns a slice into thread-local storage valid until the next FFI call.
pub fn _last_error() ?[]const u8 {
    const _code = c.demo_last_error_code();
    if (_code == 0) return null;
    const _ctx = c.demo_last_error_context();
    if (_ctx == null) return null;
    return std.mem.sliceTo(_ctx, 0);
}

/// Map the last FFI error to a typed error from the given error set.
/// Coarse fallback: returns the first declared variant. Per-code dispatch
/// will replace this once the IR exposes per-variant numeric codes.
inline fn _first_error(comptime E: type) E {
    const fields = @typeInfo(E).error_set orelse return @as(E, error.Unknown);
    if (fields.len == 0) return @as(E, error.Unknown);
    return @field(E, fields[0].name);
}

/// Errors emitted by demo operations.
pub const DemoError = error{
    InvalidInput,
    ProcessingFailed,
    OutOfMemory,
};

/// A demo configuration struct.
pub const Config = struct {
    value: i32,
    label: []const u8,
    tag: ?[]const u8,
};

/// Processing status.
pub const Status = enum {
    /// Active state.
    active,
    /// Inactive state.
    inactive,
};

/// Process input and return a result.
pub fn process(input: []const u8, count: u32) DemoError![]u8 {
    const input_z = try std.fmt.allocPrintSentinel(
        std.heap.c_allocator, "{s}", .{input}, 0);
    defer std.heap.c_allocator.free(input_z);
    const _result = c.demo_process(input_z, count);
    if (c.demo_last_error_code() != 0) {
        return _first_error(DemoError);
    }
    if (_result == null) {
        return _first_error(DemoError);
    }
    const _result_len = c.demo_process_len(input_z, count);
    return blk: {
        if (_result == null) return _first_error(DemoError);
        const slice = _result[0.._result_len];
        const owned = try std.heap.c_allocator.dupe(u8, slice);
        _free_string(_result);
        break :blk owned;
    }
;
}
