Skip to content

Validation ​

env.zig provides built-in validators and schema-based validation with error and warning support.

Validation Levels ​

Each validation result has a level field:

LevelMeaning
.errRequired field missing or invalid — must be fixed
.warningOptional field missing or invalid — informational
ConditionLevel
Required field missing.err
Required field present but invalid.err
Optional field missing (has validators or description).warning
Optional field present but invalid.warning
Optional field missing (no validators, no description)Silent (no result)

Built-in Validators ​

ValidatorDescription
validators.requiredValue must not be empty
validators.booleanValue must be a valid boolean (true/false/yes/no/1/0/on/off)
validators.integerValue must be a valid integer
validators.floatValue must be a valid float
validators.urlValue must be a valid URL
validators.emailValue must be a valid email address
validators.ipv4Value must be a valid IPv4 address
validators.hostnameValue must be a valid hostname
validators.portValue must be a valid port number (0-65535)
validators.range(min, max)Value must be within the given range
validators.minLength(min)Value must be at least min characters
validators.maxLength(max)Value must be at most max characters
validators.oneOf(allowed)Value must be one of the allowed values

Schema Definition ​

zig
const envMod = @import("env");

const schema = envMod.schema.Schema{
    .fields = &.{
        .{
            .key = "DATABASE_URL",
            .required = true,
            .validatorsList = &.{ envMod.validator.validators.required, envMod.validator.validators.url },
            .description = "Database connection URL",
        },
        .{
            .key = "PORT",
            .required = true,
            .validatorsList = &.{ envMod.validator.validators.required, envMod.validator.validators.integer },
            .description = "Server port",
        },
        .{
            .key = "LOG_LEVEL",
            .required = false,
            .defaultValue = "info",
            .validatorsList = &.{envMod.validator.validators.oneOf(&.{ "debug", "info", "warn", "error" })},
            .description = "Logging level",
        },
        .{
            .key = "API_KEY",
            .required = false,
            .validatorsList = &.{envMod.validator.validators.required},
            .description = "API secret key",
        },
    },
};

Running Validation ​

zig
const errs = try env.validate(allocator, schema);
defer allocator.free(errs);

var hasErrors = false;
var hasWarnings = false;

for (errs) |err| {
    if (err.level == .err) {
        if (!hasErrors) {
            try stdout.print("Errors:\n", .{});
            hasErrors = true;
        }
        try stdout.print("  [ERROR] {s}: {s}\n", .{ err.key, err.message });
    } else {
        if (!hasWarnings) {
            try stdout.print("\nWarnings:\n", .{});
            hasWarnings = true;
        }
        try stdout.print("  [WARN]  {s}: {s}\n", .{ err.key, err.message });
    }
}

if (!hasErrors and !hasWarnings) {
    try stdout.print("Validation passed!\n", .{});
}

Default Values ​

Fields with defaultValue or defaultFn are auto-populated if missing:

zig
.{
    .key = "TIMEOUT",
    .required = false,
    .defaultValue = "30",
    .validatorsList = &.{envMod.validator.validators.integer},
},

Custom Validators ​

Create a custom validator by implementing the ValidatorFn signature:

zig
fn myValidator(value: []const u8) ?[]const u8 {
    if (value.len < 3) return "must be at least 3 characters";
    return null;
}

See Also ​

Released under the MIT License.