✓
Passing This code compiles and runs correctly.
Code
// Test 330_050: Union accepts either state
// Tests that phantom state unions accept any matching member state
// Demonstrates: [paused|active] accepts both paused AND active states
~import "$app/connection"
// Test 1: resume() accepts 'active' state (second member of union)
~app.connection:create()
| created c1 |> app.connection:connect(conn: c1.conn)
| connected c2 |> app.connection:resume(conn: c2.conn) // active -> resume accepts it!
| resumed c3 |> app.connection:close(conn: c3.conn)
| closed |> _
// Test 2: resume() accepts 'paused' state (first member of union)
~app.connection:create()
| created c1 |> app.connection:connect(conn: c1.conn)
| connected c2 |> app.connection:pause(conn: c2.conn)
| paused c3 |> app.connection:resume(conn: c3.conn) // paused -> resume accepts it!
| resumed c4 |> app.connection:close(conn: c4.conn)
| closed |> _
// Test 3: close() accepts 'active' directly (union member)
~app.connection:create()
| created c1 |> app.connection:connect(conn: c1.conn)
| connected c2 |> app.connection:close(conn: c2.conn) // active -> close accepts it!
| closed |> _
// Test 4: close() accepts 'paused' (other union member)
~app.connection:create()
| created c1 |> app.connection:connect(conn: c1.conn)
| connected c2 |> app.connection:pause(conn: c2.conn)
| paused c3 |> app.connection:close(conn: c3.conn) // paused -> close accepts it!
| closed |> _
Imported Files
// Library module: connection
// Demonstrates phantom state unions - events that accept multiple states
const std = @import("std");
// Connection type with phantom states
const Connection = struct {
id: i32,
};
// Create a new connection - starts in 'idle' state
~pub event create {}
| created { conn: *Connection[idle] }
~proc create {
std.debug.print("Creating connection\n", .{});
const allocator = std.heap.page_allocator;
const c = allocator.create(Connection) catch unreachable;
c.* = Connection{ .id = 1 };
return .{ .created = .{ .conn = c } };
}
// Connect - transitions from idle to active
~pub event connect { conn: *Connection[idle] }
| connected { conn: *Connection[active] }
~proc connect {
std.debug.print("Connecting: {d}\n", .{conn.id});
return .{ .connected = .{ .conn = conn } };
}
// Pause - transitions from active to paused
~pub event pause { conn: *Connection[active] }
| paused { conn: *Connection[paused] }
~proc pause {
std.debug.print("Pausing: {d}\n", .{conn.id});
return .{ .paused = .{ .conn = conn } };
}
// Resume - accepts EITHER paused OR active (union!) - always returns active
// This demonstrates the core union feature: flexible input acceptance
~pub event resume { conn: *Connection[paused|active] }
| resumed { conn: *Connection[active] }
~proc resume {
std.debug.print("Resuming/continuing: {d}\n", .{conn.id});
return .{ .resumed = .{ .conn = conn } };
}
// Close - accepts active OR paused (union!) - cleans up connection
~pub event close { conn: *Connection[active|paused] }
| closed {}
~proc close {
std.debug.print("Closing: {d}\n", .{conn.id});
return .{ .closed = .{} };
}