Structs, Enums & Pattern Matching — Modeling Data
Real programs work with real-world data: products, orders, customers, messages, errors. AdeshLang models data with structs, enums, and pattern matching — the same trio used by Rust, and proven in the examples repository's e-commerce demo.
Structs: named fields
A struct is a record with named fields. Think of it as a form you fill in:
struct Price {
amount: f64;
currency: string;
}
struct Product {
id: i32;
name: string;
price: Price;
inStock: bool;
quantity: i32;
}
Create one with a struct literal:
let laptop = Product {
id: 1001,
name: "Premium Laptop",
price: Price { amount: 29.99, currency: "USD" },
inStock: true,
quantity: 15,
};
print(laptop.name); // Premium Laptop
print(laptop.price.amount); // 29.99
Output:
Premium Laptop
29.99
That is exactly examples/structures/ecommerce_example.adesh, which models a
complete e-commerce system with nested structs (Order holds a Customer and
a Product).
Structs with functions
Structs can carry behavior via extend on:
struct Point {
x: f64;
y: f64;
}
extend on Point {
fn magnitude() {
return Math.sqrt(this.x * this.x + this.y * this.y);
}
}
let p = Point { x: 3.0, y: 4.0 };
print(p.magnitude()); // 5.0
Output:
5.0
Enums: a value that is one of several variants
An enum describes a choice. Variants can carry no payload, one payload, or
several:
enum Direction {
North,
South,
East,
West
}
enum Message {
Quit,
Move(coords),
Write(text)
}
From examples/enum/basic_enum.adesh and examples/enum/payload_enum.adesh.
let dir = Direction.North();
print(dir.tag); // North
let move = Message.Move(100, 200);
print(move.tag); // Move
print(move.value); // [100, 200] (multiple payloads become an array)
Output:
North
Move
[100, 200]
Option and Result: the two enums you will use every day
AdeshLang ships two enums that turn "a missing value" and "a possible failure" into types you must handle:
let some = Some("Ajay");
let none = None();
print(some.tag); // Some
print(none.tag); // None
Output:
Some
None
enum Result {
Ok(value),
Err(error)
}
let ok = Result.Ok(42);
let fail = Result.Err("Something went wrong");
See examples/advanced_types/02_result_type.adesh — it builds Result from
scratch and matches on both variants.
Pattern matching with match
match lets you handle each variant explicitly and safely:
enum Status {
Pending,
Active(string),
Failed(i32)
}
let current = Status.Active("Session_89");
match current {
Status.Pending => print("Status is pending"),
Status.Active(info) => print("Active session:", info),
Status.Failed(code) => print("Failed with error code:", code)
}
Output:
Active session: Session_89
Matching on a Result:
fn safeDivide(a: f64, b: f64): Result {
if b == 0 {
return Result.Err("Division by zero");
}
return Result.Ok(a / b);
}
let res = safeDivide(10.0, 0.0);
match res {
Result.Ok(value) => print("Got:", value),
Result.Err(msg) => print("Error:", msg)
}
Output:
Error: Division by zero
Pattern matching replaces whole if/elif/else chains and, when used with
enums, guarantees you handled every case. See
docs/language-guide/enums-pattern-matching for the deep reference.
Real-world modeling example
This is how the repository models an order system
(examples/structures/ecommerce_example.adesh, condensed):
struct Customer {
customerId: i32;
name: string;
email: string;
}
let alice = Customer {
customerId: 5001,
name: "Alice Johnson",
email: "alice@example.com",
};
print(alice.name, alice.email);
Output:
Alice Johnson alice@example.com
Practice
Create grade.adesh:
enum Grade {
Excellent,
Good,
Fair,
Poor
}
fn gradeFor(score: i32): Grade {
if score >= 90 { return Grade.Excellent(); }
if score >= 75 { return Grade.Good(); }
if score >= 60 { return Grade.Fair(); }
return Grade.Poor();
}
let s = 82;
let g = gradeFor(s);
match g {
Grade.Excellent => print("Outstanding!"),
Grade.Good => print("Nice work!"),
Grade.Fair => print("Keep practicing."),
Grade.Poor => print("Ask for help — everyone starts somewhere.")
}
Output:
Nice work!
Summary
✅ You learned:
structdefines a named record of fields- struct literals:
Product { id: 1001, name: "…", ... } - nested structs model real-world hierarchies
extend onadds methods to a structenumdefines one-of-many variants, with payloadsSome/None(Option) andResult.Ok/Result.Errmatchhandles every variant explicitly
Next Step
Now let's give our structs real behavior with classes and object-oriented programming. Continue to OOP →