feat: add example scripts for argparse, bytes, dataset, html, markdown, uuid, wdantic, and web chat modules

Add comprehensive demo scripts showcasing the usage of multiple Wren modules including argument parsing, byte manipulation, in-memory dataset operations, HTML encoding/slugification, markdown-to-HTML conversion, UUID generation/validation, schema validation with wdantic, and a full web chat application with REST endpoints.
This commit is contained in:
2026-01-24 22:40:22 +00:00
parent 0a65272f80
commit 5a4054ec66
105 changed files with 23275 additions and 94 deletions
+35
View File
@@ -0,0 +1,35 @@
// retoor <retoor@molodetz.nl>
import "argparse" for ArgumentParser
System.print("=== Argparse Module Demo ===")
System.print("\n--- Basic Usage ---")
var parser = ArgumentParser.new("A sample program")
parser.prog = "sample"
parser.addArgument("input", {"help": "Input file"})
parser.addArgument("-o", {"long": "--output", "default": "output.txt", "help": "Output file"})
parser.addArgument("-v", {"long": "--verbose", "action": "storeTrue", "help": "Verbose output"})
parser.addArgument("-n", {"type": "int", "default": 1, "help": "Number of iterations"})
System.print("Help message:")
parser.printHelp()
System.print("\n--- Parsing Example Args ---")
var args = parser.parseArgs(["data.txt", "-v", "-n", "5", "--output", "result.txt"])
System.print("Input: %(args["input"])")
System.print("Output: %(args["output"])")
System.print("Verbose: %(args["verbose"])")
System.print("Iterations: %(args["n"])")
System.print("\n--- Count Action ---")
var parser2 = ArgumentParser.new()
parser2.addArgument("-v", {"action": "count"})
var args2 = parser2.parseArgs(["-v", "-v", "-v"])
System.print("Verbosity level: %(args2["v"])")
System.print("\n--- Append Action ---")
var parser3 = ArgumentParser.new()
parser3.addArgument("-i", {"long": "--include", "action": "append"})
var args3 = parser3.parseArgs(["-i", "module1", "-i", "module2", "--include", "module3"])
System.print("Included modules: %(args3["include"])")
+39
View File
@@ -0,0 +1,39 @@
// retoor <retoor@molodetz.nl>
import "bytes" for Bytes
System.print("=== Bytes Module Demo ===\n")
System.print("--- fromList / toList ---")
var list = [72, 101, 108, 108, 111]
var str = Bytes.fromList(list)
System.print("fromList([72, 101, 108, 108, 111]) = %(str)")
System.print("toList(%(str)) = %(Bytes.toList(str))")
System.print("\n--- length ---")
System.print("length('Hello World') = %(Bytes.length("Hello World"))")
System.print("\n--- concat ---")
var a = "Hello"
var b = " World"
System.print("concat('%(a)', '%(b)') = %(Bytes.concat(a, b))")
System.print("\n--- slice ---")
var data = "Hello World"
System.print("slice('%(data)', 0, 5) = %(Bytes.slice(data, 0, 5))")
System.print("slice('%(data)', 6, 11) = %(Bytes.slice(data, 6, 11))")
System.print("\n--- xorMask ---")
var payload = Bytes.fromList([1, 2, 3, 4, 5, 6, 7, 8])
var mask = Bytes.fromList([0x12, 0x34, 0x56, 0x78])
var masked = Bytes.xorMask(payload, mask)
System.print("Original: %(Bytes.toList(payload))")
System.print("Mask: %(Bytes.toList(mask))")
System.print("XOR'd: %(Bytes.toList(masked))")
var unmasked = Bytes.xorMask(masked, mask)
System.print("Unmasked: %(Bytes.toList(unmasked))")
System.print("\n--- Binary data handling ---")
var binary = Bytes.fromList([0, 127, 128, 255])
System.print("Binary data length: %(Bytes.length(binary))")
System.print("Binary data bytes: %(Bytes.toList(binary))")
+52
View File
@@ -0,0 +1,52 @@
// retoor <retoor@molodetz.nl>
import "dataset" for Dataset
System.print("=== Dataset Module Demo ===")
var ds = Dataset.memory()
System.print("\n--- Insert Records ---")
var users = ds["users"]
var alice = users.insert({"name": "Alice", "age": 30, "email": "alice@example.com"})
System.print("Inserted: %(alice["name"]) with uid: %(alice["uid"])")
var bob = users.insert({"name": "Bob", "age": 25, "email": "bob@example.com"})
var charlie = users.insert({"name": "Charlie", "age": 35, "email": "charlie@example.com"})
System.print("Total users: %(users.count())")
System.print("\n--- Query Records ---")
var all = users.all()
System.print("All users:")
for (user in all) {
System.print(" - %(user["name"]) (%(user["age"]))")
}
System.print("\nUsers older than 28:")
var older = users.find({"age__gt": 28})
for (user in older) {
System.print(" - %(user["name"])")
}
System.print("\n--- Update Record ---")
users.update({"uid": alice["uid"], "age": 31})
var updated = users.findOne({"uid": alice["uid"]})
System.print("Alice's new age: %(updated["age"])")
System.print("\n--- Delete Record ---")
System.print("Before delete: %(users.count()) users")
users.delete(bob["uid"])
System.print("After delete: %(users.count()) users")
System.print("\n--- Auto Schema ---")
var products = ds["products"]
products.insert({"name": "Widget", "price": 9.99})
products.insert({"name": "Gadget", "price": 19.99, "stock": 100})
System.print("Product columns: %(products.columns.keys.toList)")
System.print("\n--- Tables ---")
System.print("All tables: %(ds.tables)")
ds.close()
System.print("\nDone.")
+39
View File
@@ -0,0 +1,39 @@
// retoor <retoor@molodetz.nl>
import "html" for Html
System.print("=== HTML Module Demo ===")
System.print("\n--- URL Encoding ---")
var text = "hello world & special=chars"
var encoded = Html.urlencode(text)
var decoded = Html.urldecode(encoded)
System.print("Original: %(text)")
System.print("Encoded: %(encoded)")
System.print("Decoded: %(decoded)")
System.print("\n--- Slugify ---")
var titles = [
"Hello World",
"This is a Test Article!",
"Product Name (2024)",
"FAQ & Help"
]
for (title in titles) {
System.print("%(title) -> %(Html.slugify(title))")
}
System.print("\n--- HTML Escaping ---")
var unsafe = "<script>alert('XSS')</script>"
var safe = Html.quote(unsafe)
System.print("Unsafe: %(unsafe)")
System.print("Safe: %(safe)")
System.print("Unescaped: %(Html.unquote(safe))")
System.print("\n--- Query Parameters ---")
var params = {"name": "John Doe", "city": "New York", "age": 30}
var queryString = Html.encodeParams(params)
System.print("Params: %(params)")
System.print("Query string: %(queryString)")
var parsed = Html.decodeParams(queryString)
System.print("Parsed back: %(parsed)")
+52
View File
@@ -0,0 +1,52 @@
// retoor <retoor@molodetz.nl>
import "markdown" for Markdown
System.print("=== Markdown Module Demo ===")
var markdown = "# Welcome to Markdown
This is a **bold** statement and this is *italic*.
## Features
- Easy to read
- Easy to write
- Converts to HTML
### Code Example
Here is some `inline code`.
```
function hello() {
console.log(\"Hello, World!\")
}
```
### Links and Images
Check out [Wren](https://wren.io) for more info.
![Logo](logo.png)
> This is a blockquote.
> It can span multiple lines.
---
1. First item
2. Second item
3. Third item
That's all folks!"
System.print("\n--- Source Markdown ---")
System.print(markdown)
System.print("\n--- Generated HTML ---")
System.print(Markdown.toHtml(markdown))
System.print("\n--- Safe Mode Example ---")
var unsafe = "# Title\n\n<script>alert('xss')</script>\n\nSafe content."
System.print(Markdown.toHtml(unsafe, {"safeMode": true}))
+27
View File
@@ -0,0 +1,27 @@
// retoor <retoor@molodetz.nl>
import "uuid" for Uuid
System.print("=== UUID Module Demo ===")
System.print("\n--- Generating UUIDs ---")
for (i in 1..5) {
System.print("UUID %(i): %(Uuid.v4())")
}
System.print("\n--- UUID Validation ---")
var testUuid = Uuid.v4()
System.print("Generated: %(testUuid)")
System.print("isValid: %(Uuid.isValid(testUuid))")
System.print("isV4: %(Uuid.isV4(testUuid))")
System.print("\n--- Invalid UUID Examples ---")
var invalidUuids = [
"invalid",
"550e8400-e29b-41d4-a716",
"550e8400-e29b-41d4-a716-44665544000X",
123
]
for (uuid in invalidUuids) {
System.print("%(uuid): isValid = %(Uuid.isValid(uuid))")
}
+72
View File
@@ -0,0 +1,72 @@
// retoor <retoor@molodetz.nl>
import "wdantic" for Validator, Schema, Field
System.print("=== Wdantic Module Demo ===")
System.print("\n--- Validators ---")
var testEmail = "user@example.com"
System.print("Email '%(testEmail)' valid: %(Validator.email(testEmail))")
var testUrl = "https://example.com/path"
System.print("URL '%(testUrl)' valid: %(Validator.url(testUrl))")
var testUuid = "550e8400-e29b-41d4-a716-446655440000"
System.print("UUID '%(testUuid)' valid: %(Validator.uuid(testUuid))")
System.print("\n--- Schema Validation ---")
var userSchema = Schema.new({
"name": Field.string({"minLength": 1, "maxLength": 100}),
"age": Field.integer({"min": 0, "max": 150}),
"email": Field.email(),
"active": Field.boolean()
})
var validUser = {
"name": "John Doe",
"age": 30,
"email": "john@example.com",
"active": true
}
var result = userSchema.validate(validUser)
System.print("Valid user result: %(result.isValid)")
if (result.isValid) {
System.print("Validated data: %(result.data)")
}
System.print("\n--- Invalid Data ---")
var invalidUser = {
"name": "",
"age": -5,
"email": "not-an-email",
"active": "yes"
}
var result2 = userSchema.validate(invalidUser)
System.print("Invalid user result: %(result2.isValid)")
System.print("Errors:")
for (error in result2.errors) {
System.print(" - %(error)")
}
System.print("\n--- Optional Fields ---")
var profileSchema = Schema.new({
"username": Field.string(),
"bio": Field.optional(Field.string({"maxLength": 500})),
"website": Field.optional(Field.string())
})
var minimalProfile = {"username": "alice"}
var fullProfile = {"username": "bob", "bio": "Developer", "website": "https://bob.dev"}
System.print("Minimal profile valid: %(profileSchema.validate(minimalProfile).isValid)")
System.print("Full profile valid: %(profileSchema.validate(fullProfile).isValid)")
System.print("\n--- List Validation ---")
var tagsSchema = Schema.new({
"tags": Field.list(Field.string())
})
var tagData = {"tags": ["wren", "programming", "cli"]}
System.print("Tags valid: %(tagsSchema.validate(tagData).isValid)")
+122
View File
@@ -0,0 +1,122 @@
// retoor <retoor@molodetz.nl>
import "web" for Application, Response, View
import "wdantic" for Schema, Field
import "dataset" for Dataset
import "uuid" for Uuid
import "json" for Json
var db = Dataset.memory()
var messages = db["messages"]
var messageSchema = Schema.new({
"username": Field.string({"minLength": 1, "maxLength": 50}),
"content": Field.string({"minLength": 1, "maxLength": 500})
})
class MessagesView is View {
get(request) {
var allMessages = messages.all()
return Response.json(allMessages)
}
post(request) {
var data = request.json
var result = messageSchema.validate(data)
if (!result.isValid) {
var r = Response.json({"error": "Validation failed", "details": result.errors.map { |e| e.toString }.toList})
r.status = 400
return r
}
var msg = messages.insert({
"username": data["username"],
"content": data["content"]
})
return Response.json(msg)
}
}
class MessageView is View {
get(request) {
var id = request.params["id"]
var msg = messages.findOne({"uid": id})
if (msg == null) {
var r = Response.json({"error": "Message not found"})
r.status = 404
return r
}
return Response.json(msg)
}
delete(request) {
var id = request.params["id"]
var deleted = messages.delete(id)
if (!deleted) {
var r = Response.json({"error": "Message not found"})
r.status = 404
return r
}
return Response.json({"status": "deleted"})
}
}
var indexHtml = "<!DOCTYPE html>
<html>
<head>
<title>Chat Demo</title>
<style>
body { font-family: sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
#messages { border: 1px solid #ccc; padding: 10px; height: 300px; overflow-y: auto; margin-bottom: 10px; }
.message { margin: 5px 0; padding: 5px; background: #f5f5f5; }
.message .username { font-weight: bold; }
form { display: flex; gap: 10px; }
input, button { padding: 8px; }
input[name=content] { flex: 1; }
</style>
</head>
<body>
<h1>Chat Demo</h1>
<div id=\"messages\"></div>
<form id=\"form\">
<input name=\"username\" placeholder=\"Username\" required>
<input name=\"content\" placeholder=\"Message\" required>
<button type=\"submit\">Send</button>
</form>
<script>
async function loadMessages() {
const res = await fetch('/api/messages');
const msgs = await res.json();
const div = document.getElementById('messages');
div.innerHTML = msgs.map(m =>
'<div class=\"message\"><span class=\"username\">' + m.username + ':</span> ' + m.content + '</div>'
).join('');
div.scrollTop = div.scrollHeight;
}
document.getElementById('form').onsubmit = async (e) => {
e.preventDefault();
const form = e.target;
await fetch('/api/messages', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
username: form.username.value,
content: form.content.value
})
});
form.content.value = '';
loadMessages();
};
loadMessages();
setInterval(loadMessages, 3000);
</script>
</body>
</html>"
var app = Application.new()
app.get("/", Fn.new { |req| Response.html(indexHtml) })
app.addView("/api/messages", MessagesView)
app.addView("/api/messages/:id", MessageView)
System.print("Chat demo running on http://localhost:8080")
app.run("0.0.0.0", 8080)
+58
View File
@@ -0,0 +1,58 @@
// retoor <retoor@molodetz.nl>
import "web" for Application, Response, View
import "json" for Json
class HelloView is View {
get(request) {
return Response.text("Hello, World!")
}
}
class ApiView is View {
get(request) {
var data = {"message": "API response", "method": "GET"}
return Response.json(data)
}
post(request) {
var body = request.json
var data = {"message": "Data received", "received": body}
return Response.json(data)
}
}
class UserView is View {
get(request) {
var userId = request.params["id"]
return Response.json({"user_id": userId, "action": "get"})
}
}
var app = Application.new()
app.get("/", Fn.new { |req|
return Response.html("<h1>Welcome to Wren Web!</h1><p>A simple web framework.</p>")
})
app.addView("/hello", HelloView)
app.addView("/api", ApiView)
app.addView("/users/:id", UserView)
app.get("/greet/:name", Fn.new { |req|
var name = req.params["name"]
return Response.text("Hello, " + name + "!")
})
app.get("/session", Fn.new { |req|
var count = req.session["count"]
if (count == null) count = 0
count = count + 1
req.session["count"] = count
return Response.json({"visit_count": count})
})
app.static_("/static", "./static")
System.print("Starting server...")
app.run("0.0.0.0", 8080)