Skip to content

Examples

ghaerdi edited this page Aug 14, 2026 · 2 revisions

Examples

Basic Usage

Import Ok, Err, Result, Some, None, and Option from the library.

import { Err, None, Ok, Option, Result, Some } from "@ghaerdi/rustify";
import { match } from "@ghaerdi/rustify/match";

// --- Creating a function that returns a Result ---

function divide(
  numerator: number,
  denominator: number,
): Result<number, string> {
  if (denominator === 0) {
    return Err("Cannot divide by zero");
  }
  return Ok(numerator / denominator);
}

// --- Using the function and handling the Result ---

const result = divide(10, 2);

// Use match() to exhaustively handle both Ok and Err cases.
// Result.ok / Result.err match the variant and hand the UNWRAPPED
// value (or error) straight to the handler.
const message = match(result)
  .with(Result.ok, (value) => `Result: ${value}`)
  .with(Result.err, (error) => `Error: ${error}`)
  .exhaustive(); // compile-checked: every variant handled
console.log(message); // "Result: 5"

// Working with ok() and err() methods that return Option:
const okValue = result.ok(); // Returns Option<number>
if (okValue.isSome()) {
  console.log(`Ok value: ${okValue.unwrap()}`);
}

// Example with Option — Option.some / Option.none match the variants:
const name: Option<string> = Some("Alice");
const greeting = match(name)
  .with(Option.some, (value) => `Hello, ${value}!`)
  .with(Option.none, () => "Hello, stranger!")
  .exhaustive();
console.log(greeting); // "Hello, Alice!"

// Wrapping unsafe operations
const parsed = Result.from(() => JSON.parse('{"x": 1}')); // Ok({x: 1})
const nullable = Option.fromNullable(() => document.getElementById("app")); // Some(element) or None

Chaining with Result

import { Err, Ok, Result } from "@ghaerdi/rustify";

function parseAge(input: string): Result<number, string> {
  const num = parseInt(input, 10);
  if (isNaN(num)) return Err("Not a number");
  if (num < 0) return Err("Age cannot be negative");
  if (num > 150) return Err("Unrealistic age");
  return Ok(num);
}

const result = parseAge("25")
  .map((age) => age + 1) // Ok(26)
  .andThen((age) => Ok(age.toString())); // Ok("26")

console.log(result.unwrap()); // "26"

Chaining with Option

import { None, Option, Some } from "@ghaerdi/rustify";

const config: Option<Record<string, string>> = Some({
  theme: "dark",
  lang: "en",
});

const theme = config
  .map((c) => c.theme) // Some("dark")
  .filter((t) => t === "dark") // Some("dark")
  .unwrapOr("light"); // "dark"

console.log(theme);

Converting throwing functions

import { Option, Result } from "@ghaerdi/rustify";

// Result.from catches thrown errors
const parsed = Result.from(() => JSON.parse('{"valid": true}'));
// parsed is Ok({ valid: true })

const failed = Result.from(() => JSON.parse("invalid"));
// failed is Err("Unexpected token...")

// Option.fromNullable handles null/undefined
const element = Option.fromNullable(() => document.getElementById("app"));
// element is Some(element) or None

Pattern matching with match()

import { match, P } from "@ghaerdi/rustify/match";
import { Err, None, Ok, Option, Result, Some } from "@ghaerdi/rustify";

type Shape =
  | { type: "circle"; radius: number }
  | { type: "rect"; width: number; height: number };

// exhaustive() is checked at compile time: every Shape case must be handled.
const area = (shape: Shape): number =>
  match(shape)
    .with({ type: "circle" }, ({ radius }) => Math.PI * radius * radius)
    .with({ type: "rect" }, ({ width, height }) => width * height)
    .exhaustive();

console.log(area({ type: "circle", radius: 2 })); // ~12.57
console.log(area({ type: "rect", width: 3, height: 4 })); // 12

// Patterns can also be guards, catch-alls, and combinators:
const describe = (value: unknown): string =>
  match(value)
    .with(P.string, (s) => `a string: ${s}`)
    .with(P.number, (n) => `a number: ${n}`)
    .with(
      { type: "rect", width: P.number, height: P.number },
      ({ width }) => `a ${width}-wide rect`,
    )
    .otherwise(() => "something else");

console.log(describe("hi")); // "a string: hi"
console.log(describe({ type: "rect", width: 3, height: 4 })); // "a 3-wide rect"

// Option.some / Option.none / Result.ok / Result.err are ready-made
// patterns for the library's own types: they match the variant AND hand the
// unwrapped value (or error) straight to the handler.
const label = (value: Result<number, string> | Option<number>): string =>
  match(value)
    .with(Result.ok, (n) => `ok: ${n}`)
    .with(Result.err, (e) => `err: ${e}`)
    .with(Option.some, (n) => `some: ${n}`)
    .with(Option.none, () => "none")
    .exhaustive();

console.log(label(Ok(5))); // "ok: 5"
console.log(label(Err("boom"))); // "err: boom"
console.log(label(Some(5))); // "some: 5"
console.log(label(None())); // "none"

See Also

Clone this wiki locally