Files
wren/manual/api/wdantic.html
T
retoor 819bbd5091 feat: add fswatch, sysinfo, and udp demo scripts plus reorder manual sidebar links
Add three new example scripts demonstrating the fswatch, sysinfo, and udp modules with file watching, system metrics, and UDP echo server/client patterns. Reorder the manual API sidebar navigation to list modules alphabetically, removing deprecated entries like websocket, tls, net, json, regex, jinja, os, signal, subprocess, sqlite, and timer while adding argparse, dataset, fswatch, and html.
2026-01-25 12:09:28 +00:00

429 lines
20 KiB
HTML

<!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>
<li><a href="string.html">String</a></li>
<li><a href="number.html">Num</a></li>
<li><a href="argparse.html">argparse</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="dataset.html">dataset</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="env.html">env</a></li>
<li><a href="fswatch.html">fswatch</a></li>
<li><a href="html.html">html</a></li>
<li><a href="http.html">http</a></li>
<li><a href="io.html">io</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="json.html">json</a></li>
<li><a href="markdown.html">markdown</a></li>
<li><a href="math.html">math</a></li>
<li><a href="net.html">net</a></li>
<li><a href="os.html">os</a></li>
<li><a href="pathlib.html">pathlib</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sysinfo.html">sysinfo</a></li>
<li><a href="tempfile.html">tempfile</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="udp.html">udp</a></li>
<li><a href="uuid.html">uuid</a></li>
<li><a href="wdantic.html" class="active">wdantic</a></li>
<li><a href="web.html">web</a></li>
<li><a href="websocket.html">websocket</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
<li><a href="../tutorials/http-client.html">HTTP Client</a></li>
<li><a href="../tutorials/websocket-chat.html">WebSocket Chat</a></li>
<li><a href="../tutorials/database-app.html">Database App</a></li>
<li><a href="../tutorials/template-rendering.html">Templates</a></li>
<li><a href="../tutorials/cli-tool.html">CLI Tool</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>
<li><a href="../howto/http-requests.html">HTTP Requests</a></li>
<li><a href="../howto/json-parsing.html">JSON Parsing</a></li>
<li><a href="../howto/regex-patterns.html">Regex Patterns</a></li>
<li><a href="../howto/file-operations.html">File Operations</a></li>
<li><a href="../howto/async-operations.html">Async Operations</a></li>
<li><a href="../howto/error-handling.html">Error Handling</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>