Skip to content

API Reference

Every entry is a Wyn-callable function written as Namespace.method(args) -> ReturnType. Call them with dot syntax, e.g. Crypto.sha256("hello").

221 callable functions across 29 modules.

Args

3 functions

  • Args.get(name) -> string
  • Args.has(name) -> bool
  • Args.positional() -> array

Base64

2 functions

  • Base64.encode(data) -> string
  • Base64.decode(data) -> string

Crypto

8 functions

  • Crypto.hash32(data) -> int
  • Crypto.hash64(data) -> int
  • Crypto.sha1(data) -> string
  • Crypto.sha1_base64(data) -> string
  • Crypto.sha256(data) -> string
  • Crypto.md5(data) -> string
  • Crypto.hmac_sha256(key, data) -> string
  • Crypto.random_bytes(n) -> string

Csv

8 functions

  • Csv.parse(text) -> int
  • Csv.row_count(handle) -> int
  • Csv.get(handle, row, col) -> string
  • Csv.get_field(handle, row, header) -> string
  • Csv.col_count(handle, row) -> int
  • Csv.header(handle, col) -> string
  • Csv.header_count(handle) -> int
  • Csv.write(path, rows)

Data

2 functions

  • Data.save(path, map)
  • Data.load(path) -> HashMap

DateTime

16 functions

  • DateTime.now() -> int
  • DateTime.millis() -> int
  • DateTime.micros() -> int
  • DateTime.format(timestamp, fmt) -> string
  • DateTime.sleep(seconds)
  • DateTime.diff(a, b) -> int
  • DateTime.add_seconds(t, n) -> int
  • DateTime.to_iso(timestamp) -> string
  • DateTime.format_duration(ms) -> string
  • DateTime.day_of_week(timestamp) -> int
  • DateTime.year(timestamp) -> int
  • DateTime.month(timestamp) -> int
  • DateTime.day(timestamp) -> int
  • DateTime.hour(timestamp) -> int
  • DateTime.minute(timestamp) -> int
  • DateTime.second(timestamp) -> int

Db

11 functions

  • Db.open(path) -> int
  • Db.exec(handle, sql) -> int
  • Db.query(handle, sql) -> string
  • Db.query_one(handle, sql) -> string
  • Db.exec_p(handle, sql, params) -> int
  • Db.query_p(handle, sql, params) -> string
  • Db.last_insert_id(handle) -> int
  • Db.error(handle) -> string
  • Db.close(handle)
  • Db.escape(str) -> string
  • Db.table_exists(handle, table_name) -> int

Encoding

5 functions

  • Encoding.base64_encode(data) -> string
  • Encoding.base64_decode(data) -> string
  • Encoding.hex_encode(data) -> string
  • Encoding.hex_decode(hex) -> string
  • Encoding.csv_parse(csv) -> string

Env

3 functions

  • Env.get(name) -> string
  • Env.set(name, value) -> int
  • Env.all() - does not work as documented. The checker types the result int, so assigning it fails to build (initializing 'long long' from 'WynArray'). Filed.

File

23 functions

  • File.read(p) -> string
  • File.read_lines(p) -> string
  • File.write(p, d) -> int
  • File.exists(p) -> int
  • File.delete(p) -> int
  • File.copy(s, d) -> int
  • File.move(s, d) -> int
  • File.size(p) -> int
  • File.is_dir(p) -> int
  • File.is_file(p) -> int
  • File.mkdir(p) -> int
  • File.list_dir(p) -> string
  • File.append(p, d) -> int
  • File.cwd() -> string
  • File.open(path, mode) -> int
  • File.read_line(handle) -> string
  • File.write_line(handle, data) -> int
  • File.eof(handle) -> int
  • File.close(handle)
  • File.rename(old_path, new_path) -> int
  • File.glob(pattern) -> string
  • File.walk_dir(path) -> string
  • File.temp_file() -> string

HashMap

Create with HashMap(), then use string keys and values:

wyn
m = HashMap.new()
m.set("name", "Wyn")
print(m.get("name"))              // Wyn
print(m.len().to_string())        // 1
print(m.has("name").to_string())  // true
m.remove("name")
keys = m.keys()                   // []

Methods (dot syntax on a HashMap value):

  • .set(key, value) - set a key-value pair
  • .get(key) -> string - value for a key
  • .has(key) -> bool - whether a key exists
  • .len() -> int - number of entries
  • .remove(key) - remove a key
  • .keys() -> array - all keys

HashSet

1 function

  • HashSet.new() -> HashSet

Input (global builtins)

3 functions - not namespaced, callable anywhere.

  • input_line() -> string - read one line from stdin, newline stripped
  • input() -> int - read one line and parse it as an integer
  • input_float() -> float - read one line and parse it as a float

input() and input_float() validate the whole line and panic on anything else (changed in v1.21.0 - they previously returned 0 at exit 0, which turned bad input into a wrong answer):

$ echo abc | ./prog
panic: input(): "abc" is not a valid integer; use input_line() to read text

$ printf '' | ./prog
panic: input(): end of input (expected an integer)

12abc is rejected rather than read as 12, the trailing newline is consumed (so a following input_line() returns the next line rather than ""), and 64-bit values survive. Set WYN_LENIENT=1 to warn and return 0 instead of aborting, if you are migrating a program that relied on the old behaviour. Use input_line() when the input is text.

Http

18 functions

  • Http.post(url, body) -> string
  • Http.status(resp) -> int
  • Http.body(resp) -> string
  • Http.header(resp, name) -> string
  • Http.free(resp)
  • Http.respond(client_fd, status, content_type, body)
  • Http.route_match(pattern, path, params) -> int
  • Http.parse_request(raw) -> HashMap
  • Http.ctx_fd(ctx) -> int
  • Http.respond_json(fd, status, json)
  • Http.respond_html(fd, status, html)
  • Http.serve(port) -> int
  • Http.accept(server_fd) -> string - blocks for the next request. Since v1.21.0 it skips a connection that sends no request and keeps accepting, so it never returns "". Before that it did, and the documented .split_at("|", 3).to_int() idiom then panicked on the empty string - one unauthenticated packet, or an ordinary TCP health check, port scan or browser preconnect, killed the server process.
  • Http.close_server(fd)
  • Http.get_json(url) -> int
  • Http.post_json(url, data) -> int
  • Http.set_timeout(seconds)
  • Http.timeout() -> int

Json

19 functions

  • Json.new() -> Json
  • Json.set(j, k, v)
  • Json.set_string(j, k, v)
  • Json.set_int(j, k, v)
  • Json.set_bool(j, k, v)
  • Json.stringify(j) -> string
  • Json.parse(text) -> int
  • Json.get(root, key) -> string
  • Json.get_int(root, key) -> int
  • Json.has(root, key) -> int
  • Json.array_len(node) -> int
  • Json.array_get(node, index) -> int
  • Json.node_str(node) -> string
  • Json.keys(root) -> string
  • Json.get_float(root, key) -> float
  • Json.get_bool(root, key) -> int
  • Json.get_array(root, key) -> int
  • Json.get_object(root, key) -> int
  • Json.to_pretty_string(j) -> string

Log

5 functions

  • Log.set_level(level)
  • Log.debug(msg)
  • Log.info(msg)
  • Log.warn(msg)
  • Log.error(msg)

Math

26 functions

  • Math.sin(x) -> float
  • Math.cos(x) -> float
  • Math.tan(x) -> float
  • Math.sqrt(x) -> float
  • Math.pow(base, exp) -> float
  • Math.floor(x) -> float
  • Math.ceil(x) -> float
  • Math.round_to(x, places) -> float
  • Math.atan2(y, x) -> float
  • Math.pi() -> float
  • Math.e() -> float
  • Math.round(x) -> float
  • Math.abs(x) -> int
  • Math.max(a, b) -> float
  • Math.min(a, b) -> float
  • Math.checked_add(a, b) -> int
  • Math.checked_sub(a, b) -> int
  • Math.checked_mul(a, b) -> int
  • Math.random() -> float
  • Math.log(x) -> float
  • Math.log10(x) -> float
  • Math.exp(x) -> float
  • Math.clamp(x, lo, hi) -> int
  • Math.sign(x) -> int
  • Math.lerp(a, b, t) -> float
  • Math.map_range(x, in_min, in_max, out_min, out_max) -> float

Net

6 functions

  • Net.listen(port) -> int
  • Net.connect(host, port) -> int
  • Net.send(sockfd, data) -> int
  • Net.recv(sockfd) -> string
  • Net.close(sockfd) -> int
  • Net.resolve(hostname) -> string

Os

6 functions

  • Os.platform() -> string
  • Os.arch() -> string
  • Os.hostname() -> string
  • Os.pid() -> int
  • Os.temp_dir() -> string
  • Os.home_dir() -> string

Path

4 functions

  • Path.basename(p) -> string
  • Path.dirname(p) -> string
  • Path.extension(p) -> string
  • Path.join(a, b) -> string

Process

2 functions

  • Process.exec_capture(cmd) -> string
  • Process.exec_status(cmd) -> int

Regex

5 functions

  • Regex.match(s, p) -> bool - whether the pattern matches anywhere
  • Regex.replace(s, p, r) -> string - replace every match
  • Regex.find(s, p) -> int - byte offset of the first match, or -1
  • Regex.find_all(s, p) -> string - one string, one match per line
  • Regex.split(s, p) -> string - one string, one field per line

find_all and split return newline-joined strings, not arrays. Iterate them with .trim().split("\n"):

wyn
fn main() {
    text = "mail [email protected] or [email protected]"
    emails = Regex.find_all(text, "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}")
    for email in emails.trim().split("\n") { println(email) }
}

There are no capture groups. Regex.match returns a bool - there is no match object, no .group(n), no named groups. Extract fields with .split() or .substring() after matching.

The shorthand classes \d, \w and \s are not supported, and they fail silently - \d is matched as a literal d, so Regex.replace(s, "\\d+", "N") turns "disk" into "Nisk" and leaves the digits alone. Use explicit character classes, which work correctly:

Instead ofWrite
\d[0-9]
\w[A-Za-z0-9_]
\s[ \t\n]

Supported: literals, ., character classes (including escapes inside them, e.g. [ \t]), *, +, ?, {n}, {n,m}, alternation (a|b), and the ^/$ anchors. Not supported: backreferences, lookaround, capture-group extraction, and the shorthand classes above.

Socket

8 functions

  • Socket.connect(host, port) -> int
  • Socket.send(sock, data, len) -> int
  • Socket.recv(sock, max_len) -> string
  • Socket.close(sock)
  • Socket.set_timeout(sock, seconds) -> int
  • Socket.set_nonblocking(sock) -> int
  • Socket.poll_read(sock, timeout_ms) -> int
  • Socket.read_line(sock) -> string

StringBuilder

8 functions

  • StringBuilder.new() -> int
  • StringBuilder.append(handle, s)
  • StringBuilder.to_string(handle) -> string
  • StringBuilder.len(handle) -> int
  • StringBuilder.clear(handle)
  • StringBuilder.free(handle)
  • StringBuilder.append_int(handle, val)
  • StringBuilder.append_line(handle, s)

System

9 functions

  • System.shell_escape(s) -> string
  • System.exec(cmd) -> string
  • System.exec_code(cmd) -> int
  • System.exit(code)
  • System.env(key) -> string
  • System.set_env(key, value) -> int
  • System.args() -> array
  • System.gc()
  • System.load_env(path)

Task

12 functions

  • Task.value(initial) -> int
  • Task.get(handle) -> int
  • Task.set(handle, value)
  • Task.add(handle, amount)
  • Task.free_value(handle)
  • Task.channel(capacity) -> int
  • Task.send(handle, value)
  • Task.recv(handle) -> int
  • Task.close(handle)
  • Task.try_recv(handle) -> int? - Some(v) when a value is ready, none when empty (changed in v1.20; the old two-argument out-param form no longer exists)
  • Task.select_2(ch1, ch2) -> int
  • Task.select_3(ch1, ch2, ch3) -> int

Toml

3 functions

  • Toml.parse(text) -> int
  • Toml.get(handle, key) -> string
  • Toml.parse_file(path) -> int

Url

2 functions

  • Url.encode(str) -> string
  • Url.decode(str) -> string

Uuid

2 functions

  • Uuid.generate() -> string
  • Uuid.v4() -> string

Ws

4 functions. All four currently fail to link (Ws.connect, Ws.send, Ws.recv, Ws.close) - they type-check and then the build fails at the linker. Filed; do not build on these yet.

  • Ws.connect(url) -> int
  • Ws.send(sock, msg) -> int
  • Ws.recv(sock) -> string
  • Ws.close(sock)

See Also

MIT License - v1.21.0