Skip to content

Structs & Records

Structs in Wysna represent product types (records) containing named fields. They are the primary tool for modeling domain entities with explicit, type-checked schemas.

Declare a struct using the struct keyword followed by field names and their explicit types:

struct UserProfile {
id: int
username: str
email: str
is_active: bool
}

Structs are instantiated by specifying named field values:

struct UserProfile {
id: int
username: str
email: str
is_active: bool
}
fn main() -> unit {
let user = UserProfile {
id: 101,
username: "washo",
email: "washo@wysofia.com",
is_active: true,
}
print("User ID:", user.id)
print("Username:", user.username)
}

Every field declared in the struct must be provided upon initialization. Field initialization order does not have to match declaration order.


Just like scalar types, fields of a struct cannot be reassigned if the variable binding was created with let:

struct UserProfile {
id: int
username: str
email: str
is_active: bool
}
fn main() -> unit {
let admin = UserProfile {
id: 1,
username: "admin",
email: "admin@internal",
is_active: true,
}
# admin.is_active = false # Compile Error: Cannot mutate fields of immutable binding `admin`
let mut editable_user = admin
editable_user.is_active = false # Permitted! Triggers CoW for fields if shared.
print("Admin active:", admin.is_active) # true
print("Editable active:", editable_user.is_active) # false
}

Structs can be composed hierarchically:

struct Coordinates {
lat: float
lon: float
}
struct LocationMarker {
name: str
coords: Coordinates
}
fn main() -> unit {
let loc = LocationMarker {
name: "Quito, Ecuador",
coords: Coordinates {
lat: -0.1807,
lon: -78.4678,
},
}
print("Location:", loc.name, loc.coords.lat, loc.coords.lon)
}