Skip to main content

Data Structures

Oxide provides struct and enum definitions with familiar syntax.

Structs

Oxide uses tuple-style struct syntax with named fields:

struct Point(x: Int, y: Int)

struct User(
name: String,
age: Int,
active: Bool
)

Transpiles to:

struct Point { x: isize, y: isize }

struct User { name: String, age: isize, active: bool }

Instantiation

Structs use parenthesis syntax for initialization:

// Positional arguments
let p = Point(10, 20)

// Named arguments
let p = Point(x = 10, y = 20)

// Field access
let xVal = p.x
let yVal = p.y
Syntax Distinction

Structs must use parenthesis syntax Struct(field = value), while unions must use brace syntax Union { field: value }. The LSP will show an error if you use the wrong syntax.

Unit Structs

Structs without fields:

struct Empty

public struct Marker

Transpiles to:

struct Empty;

pub struct Marker;

Instantiation:

let empty = Empty()
let marker = Marker()

Struct Update Syntax

Create new structs by copying from existing ones:

struct Point(x: Int, y: Int, z: Int)

let origin = Point(x = 0, y = 0, z = 0)
let movedX = Point(x = 10, ..origin) // Copy y, z from origin
let movedXY = Point(x = 5, y = 15, ..origin)

Transpiles to:

let origin = Point { x: 0, y: 0, z: 0 };
let moved_x = Point { x: 10, ..origin };
let moved_xy = Point { x: 5, y: 15, ..origin };

Generic Structs

struct Wrapper<T>(value: T)

struct Container<T: Clone>(items: Vec<T>)

struct RefHolder<'a, T>(inner: &'a T)

Visibility

public struct PublicStruct(
public name: String, // Public field
internal age: Int, // Crate-visible field
private secret: String // Private field
)

Enums

Swift-style case syntax with camelCase naming:

enum Status {
case active
case inactive
case pending
}

enum Result<T, E> {
case success(value: T)
case failure(error: E)
}

enum Message {
case text(content: String)
case image(url: String, width: Int, height: Int)
case quit
}

Transpiles to:

#[allow(non_camel_case_types)]
enum Status {
active,
inactive,
pending,
}

enum Result<T, E> {
success { value: T },
failure { error: E },
}

enum Message {
text { content: String },
image { url: String, width: isize, height: isize },
quit,
}

Using Enums

let status = Status.active       // Dot syntax
let result = Result.success(value = 42)

match status {
Status.active -> println!("Running")
Status.inactive -> println!("Stopped")
Status.pending -> println!("Waiting")
}

Enum Methods

Add methods with extension:

extension Status {
fn isRunning(): Bool {
match self {
Status.active -> true
else -> false
}
}
}

Type Aliases

Create aliases for complex types:

type StringResult = Result<String, String>
type IntList = Vec<Int>
type Handler = fn(Request) -> Response

Transpiles to:

type StringResult = Result<String, String>;
type IntList = Vec<isize>;
type Handler = fn(Request) -> Response;

Unions

Low-level memory representation for FFI. Must use unsafe keyword.

Unions use brace syntax for initialization (unlike structs which use parenthesis syntax):

unsafe union IntOrFloat {
intVal: Int,
floatVal: Float64
}

fn main() {
unsafe {
let data = IntOrFloat { intVal: 42 } // Note: brace syntax
let i = data.intVal
}
}

Transpiles to:

union IntOrFloat {
int_val: isize,
float_val: f64,
}

fn main() {
unsafe {
let data = IntOrFloat { int_val: 42 };
let i = data.int_val;
}
}
warning

Union field access requires unsafe blocks. Accessing the wrong variant is undefined behavior.

Attributes

Derive traits and add attributes:

@[derive(Debug, Clone, PartialEq)]
struct Point(x: Int, y: Int)

@[derive(Debug)]
enum Color {
case red
case green
case blue
}

Transpiles to:

#[derive(Debug, Clone, PartialEq)]
struct Point { x: isize, y: isize }

#[derive(Debug)]
enum Color {
red,
green,
blue,
}

See Also

  • Types - Type system overview
  • Traits - Trait definitions and implementations
  • Ownership - Struct ownership patterns