2026-01-25 01:47:47 +00:00
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > wdantic - Wren-CLI Manual</ title >
< link rel = "stylesheet" href = "../css/style.css" >
</ head >
< body >
< button class = "mobile-menu-toggle" > Menu</ button >
< div class = "container" >
< aside class = "sidebar" >
< div class = "sidebar-header" >
< h1 >< a href = "../index.html" > Wren-CLI</ a ></ h1 >
< div class = "version" > v0.4.0</ div >
</ div >
< nav class = "sidebar-nav" >
< div class = "section" >
< span class = "section-title" > Getting Started</ span >
< ul >
< li >< a href = "../getting-started/index.html" > Overview</ a ></ li >
< li >< a href = "../getting-started/installation.html" > Installation</ a ></ li >
< li >< a href = "../getting-started/first-script.html" > First Script</ a ></ li >
< li >< a href = "../getting-started/repl.html" > Using the REPL</ a ></ li >
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > Language</ span >
< ul >
< li >< a href = "../language/index.html" > Syntax Overview</ a ></ li >
< li >< a href = "../language/classes.html" > Classes</ a ></ li >
< li >< a href = "../language/methods.html" > Methods</ a ></ li >
< li >< a href = "../language/control-flow.html" > Control Flow</ a ></ li >
< li >< a href = "../language/fibers.html" > Fibers</ a ></ li >
< li >< a href = "../language/modules.html" > Modules</ a ></ li >
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > API Reference</ span >
< ul >
< li >< a href = "index.html" > Overview</ a ></ li >
2026-01-25 03:58:39 +00:00
< li >< a href = "string.html" > String</ a ></ li >
< li >< a href = "number.html" > Num</ a ></ li >
2026-01-25 01:47:47 +00:00
< li >< a href = "http.html" > http</ a ></ li >
< li >< a href = "websocket.html" > websocket</ a ></ li >
< li >< a href = "tls.html" > tls</ a ></ li >
< li >< a href = "net.html" > net</ a ></ li >
< li >< a href = "dns.html" > dns</ a ></ li >
< li >< a href = "json.html" > json</ a ></ li >
< li >< a href = "base64.html" > base64</ a ></ li >
< li >< a href = "regex.html" > regex</ a ></ li >
< li >< a href = "jinja.html" > jinja</ a ></ li >
< li >< a href = "crypto.html" > crypto</ a ></ li >
< li >< a href = "os.html" > os</ a ></ li >
< li >< a href = "env.html" > env</ a ></ li >
< li >< a href = "signal.html" > signal</ a ></ li >
< li >< a href = "subprocess.html" > subprocess</ a ></ li >
< li >< a href = "sqlite.html" > sqlite</ a ></ li >
< li >< a href = "datetime.html" > datetime</ a ></ li >
< li >< a href = "timer.html" > timer</ a ></ li >
< li >< a href = "io.html" > io</ a ></ li >
2026-01-25 03:58:39 +00:00
< li >< a href = "pathlib.html" > pathlib</ a ></ li >
2026-01-25 01:47:47 +00:00
< li >< a href = "scheduler.html" > scheduler</ a ></ li >
< li >< a href = "math.html" > math</ a ></ li >
< li >< a href = "uuid.html" > uuid</ a ></ li >
< li >< a href = "html.html" > html</ a ></ li >
< li >< a href = "argparse.html" > argparse</ a ></ li >
< li >< a href = "wdantic.html" class = "active" > wdantic</ a ></ li >
< li >< a href = "dataset.html" > dataset</ a ></ li >
< li >< a href = "markdown.html" > markdown</ a ></ li >
< li >< a href = "web.html" > web</ a ></ li >
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > Tutorials</ span >
< ul >
< li >< a href = "../tutorials/index.html" > Tutorial List</ a ></ li >
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > How-To Guides</ span >
< ul >
< li >< a href = "../howto/index.html" > How-To List</ a ></ li >
</ ul >
</ div >
</ nav >
</ aside >
< main class = "content" >
< nav class = "breadcrumb" >
< a href = "../index.html" > Home</ a >
< span class = "separator" > /</ span >
< a href = "index.html" > API Reference</ a >
< span class = "separator" > /</ span >
< span > wdantic</ span >
</ nav >
< article >
< h1 > wdantic</ h1 >
< p > The < code > wdantic</ code > module provides data validation similar to Python's Pydantic. It includes standalone validators and a schema-based validation system for structured data.</ p >
< pre >< code > import "wdantic" for Validator, Field, Schema, ValidationResult</ code ></ pre >
< h2 > Validator Class</ h2 >
< div class = "class-header" >
< h3 > Validator</ h3 >
< p > Standalone validation functions</ p >
</ div >
< h3 > Static Methods</ h3 >
< div class = "method-signature" >
< span class = "method-name" > Validator.email</ span > (< span class = "param" > value</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Validates email address format.</ p >
< pre >< code > Validator.email("user@example.com") // true
Validator.email("invalid") // false</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > Validator.domain</ span > (< span class = "param" > value</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Validates domain name format.</ p >
< pre >< code > Validator.domain("example.com") // true
Validator.domain("localhost") // false</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > Validator.url</ span > (< span class = "param" > value</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Validates HTTP/HTTPS URL format.</ p >
< pre >< code > Validator.url("https://example.com/path") // true
Validator.url("ftp://example.com") // false</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > Validator.uuid</ span > (< span class = "param" > value</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Validates UUID format.</ p >
< pre >< code > Validator.uuid("550e8400-e29b-41d4-a716-446655440000") // true</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > Validator.safeStr</ span > (< span class = "param" > value</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Checks if string contains only printable ASCII characters (32-126).</ p >
< pre >< code > Validator.safeStr("Hello World") // true
Validator.safeStr("Hello\x00") // false</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > Validator.base64</ span > (< span class = "param" > value</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Validates Base64 encoding format.</ p >
< pre >< code > Validator.base64("SGVsbG8=") // true
Validator.base64("invalid!") // false</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > Validator.json</ span > (< span class = "param" > value</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Checks if string is valid JSON.</ p >
< pre >< code > Validator.json("{\"key\": \"value\"}") // true
Validator.json("{invalid}") // false</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > Validator.ipv4</ span > (< span class = "param" > value</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Validates IPv4 address format.</ p >
< pre >< code > Validator.ipv4("192.168.1.1") // true
Validator.ipv4("256.0.0.1") // false</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > Validator.minLength</ span > (< span class = "param" > value</ span > , < span class = "param" > min</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Checks minimum length of string or list.</ p >
< div class = "method-signature" >
< span class = "method-name" > Validator.maxLength</ span > (< span class = "param" > value</ span > , < span class = "param" > max</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Checks maximum length of string or list.</ p >
< div class = "method-signature" >
< span class = "method-name" > Validator.range</ span > (< span class = "param" > value</ span > , < span class = "param" > min</ span > , < span class = "param" > max</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Checks if number is within range (inclusive).</ p >
< pre >< code > Validator.range(5, 1, 10) // true
Validator.range(15, 1, 10) // false</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > Validator.positive</ span > (< span class = "param" > value</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Checks if number is positive (greater than 0).</ p >
< div class = "method-signature" >
< span class = "method-name" > Validator.negative</ span > (< span class = "param" > value</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Checks if number is negative (less than 0).</ p >
< div class = "method-signature" >
< span class = "method-name" > Validator.integer</ span > (< span class = "param" > value</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Checks if number is an integer (no decimal part).</ p >
< div class = "method-signature" >
< span class = "method-name" > Validator.regex</ span > (< span class = "param" > value</ span > , < span class = "param" > pattern</ span > ) → < span class = "type" > Bool</ span >
</ div >
< p > Tests if value matches a regular expression pattern.</ p >
< pre >< code > Validator.regex("abc123", "^[a-z]+[0-9]+$") // true</ code ></ pre >
< h2 > Field Class</ h2 >
< div class = "class-header" >
< h3 > Field</ h3 >
< p > Factory for creating field definitions</ p >
</ div >
< h3 > Static Methods</ h3 >
< div class = "method-signature" >
< span class = "method-name" > Field.string</ span > () → < span class = "type" > StringField</ span >
</ div >
< div class = "method-signature" >
< span class = "method-name" > Field.string</ span > (< span class = "param" > options</ span > ) → < span class = "type" > StringField</ span >
</ div >
< p > Creates a string field. Options: < code > minLength</ code > , < code > maxLength</ code > , < code > pattern</ code > , < code > required</ code > , < code > default</ code > .</ p >
< div class = "method-signature" >
< span class = "method-name" > Field.integer</ span > () → < span class = "type" > IntegerField</ span >
</ div >
< div class = "method-signature" >
< span class = "method-name" > Field.integer</ span > (< span class = "param" > options</ span > ) → < span class = "type" > IntegerField</ span >
</ div >
< p > Creates an integer field. Options: < code > min</ code > , < code > max</ code > , < code > required</ code > , < code > default</ code > .</ p >
< div class = "method-signature" >
< span class = "method-name" > Field.number</ span > () → < span class = "type" > NumberField</ span >
</ div >
< div class = "method-signature" >
< span class = "method-name" > Field.number</ span > (< span class = "param" > options</ span > ) → < span class = "type" > NumberField</ span >
</ div >
< p > Creates a number field (integer or float). Options: < code > min</ code > , < code > max</ code > , < code > required</ code > , < code > default</ code > .</ p >
< div class = "method-signature" >
< span class = "method-name" > Field.email</ span > () → < span class = "type" > EmailField</ span >
</ div >
< p > Creates a field that validates email format.</ p >
< div class = "method-signature" >
< span class = "method-name" > Field.boolean</ span > () → < span class = "type" > BooleanField</ span >
</ div >
< p > Creates a boolean field.</ p >
< div class = "method-signature" >
< span class = "method-name" > Field.list</ span > (< span class = "param" > itemType</ span > ) → < span class = "type" > ListField</ span >
</ div >
< p > Creates a list field with typed items.</ p >
< div class = "method-signature" >
< span class = "method-name" > Field.map</ span > () → < span class = "type" > MapField</ span >
</ div >
< p > Creates a map/object field.</ p >
< div class = "method-signature" >
< span class = "method-name" > Field.optional</ span > (< span class = "param" > fieldDef</ span > ) → < span class = "type" > OptionalField</ span >
</ div >
< p > Makes any field optional (not required).</ p >
< h2 > Schema Class</ h2 >
< div class = "class-header" >
< h3 > Schema</ h3 >
< p > Validates data against a field definition map</ p >
</ div >
< h3 > Constructor</ h3 >
< div class = "method-signature" >
< span class = "method-name" > Schema.new</ span > (< span class = "param" > definition</ span > ) → < span class = "type" > Schema</ span >
</ div >
< p > Creates a schema from a map of field names to field definitions.</ p >
< h3 > Instance Methods</ h3 >
< div class = "method-signature" >
< span class = "method-name" > validate</ span > (< span class = "param" > data</ span > ) → < span class = "type" > ValidationResult</ span >
</ div >
< p > Validates data against the schema.</ p >
< div class = "method-signature" >
< span class = "method-name" > validateOrAbort</ span > (< span class = "param" > data</ span > ) → < span class = "type" > Map</ span >
</ div >
< p > Validates data and aborts on failure. Returns validated data on success.</ p >
< h2 > ValidationResult Class</ h2 >
< div class = "class-header" >
< h3 > ValidationResult</ h3 >
< p > Result of schema validation</ p >
</ div >
< h3 > Properties</ h3 >
< div class = "method-signature" >
< span class = "method-name" > isValid</ span > → < span class = "type" > Bool</ span >
</ div >
< p > Whether validation passed.</ p >
< div class = "method-signature" >
< span class = "method-name" > errors</ span > → < span class = "type" > List</ span >
</ div >
< p > List of ValidationError objects.</ p >
< div class = "method-signature" >
< span class = "method-name" > data</ span > → < span class = "type" > Map</ span >
</ div >
< p > Validated and coerced data (null if invalid).</ p >
< h2 > Examples</ h2 >
< h3 > Basic Schema Validation</ h3 >
< pre >< code > import "wdantic" for Field, Schema
var userSchema = Schema.new({
"name": Field.string({"minLength": 1, "maxLength": 100}),
"email": Field.email(),
"age": Field.integer({"min": 0, "max": 150})
})
var result = userSchema.validate({
"name": "Alice",
"email": "alice@example.com",
"age": 30
})
if (result.isValid) {
System.print("Valid: %(result.data)")
} else {
for (error in result.errors) {
System.print("Error: %(error)")
}
}</ code ></ pre >
< h3 > Optional Fields</ h3 >
< pre >< code > import "wdantic" for Field, Schema
var schema = Schema.new({
"title": Field.string(),
"description": Field.optional(Field.string()),
"tags": Field.optional(Field.list(Field.string()))
})
var result = schema.validate({
"title": "My Post"
})
System.print(result.isValid) // true</ code ></ pre >
< h3 > Nested Lists</ h3 >
< pre >< code > import "wdantic" for Field, Schema
var schema = Schema.new({
"numbers": Field.list(Field.integer({"min": 0}))
})
var result = schema.validate({
"numbers": [1, 2, 3, -1] // -1 will fail
})
System.print(result.isValid) // false</ code ></ pre >
< h3 > Using validateOrAbort</ h3 >
< pre >< code > import "wdantic" for Field, Schema
var schema = Schema.new({
"username": Field.string({"minLength": 3}),
"password": Field.string({"minLength": 8})
})
var data = schema.validateOrAbort({
"username": "admin",
"password": "secret123"
})</ code ></ pre >
< h3 > Standalone Validators</ h3 >
< pre >< code > import "wdantic" for Validator
var email = "user@example.com"
if (Validator.email(email)) {
System.print("Valid email")
}
var ip = "192.168.1.1"
if (Validator.ipv4(ip)) {
System.print("Valid IP address")
}
var jsonStr = "{\"key\": 123}"
if (Validator.json(jsonStr)) {
System.print("Valid JSON")
}</ code ></ pre >
< div class = "admonition note" >
< div class = "admonition-title" > Note</ div >
< p > Field types automatically coerce values when possible. For example, < code > IntegerField</ code > will convert the string < code > "42"</ code > to the number < code > 42</ code > .</ p >
</ div >
</ article >
< footer class = "page-footer" >
< a href = "argparse.html" class = "prev" > argparse</ a >
< a href = "dataset.html" class = "next" > dataset</ a >
</ footer >
</ main >
</ div >
< script src = "../js/main.js" ></ script >
</ body >
</ html >