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
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;
}
}
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,
}