using Statum; using Invercargill; using Invercargill.DataStructures; namespace Example { /** * `POST /_statum/action/{guid}` — logs in: reads the submitted name, builds a * session `auth` slot from typed models (public + private), embedding a * `logout` action reference, and redirects home. */ public class LoginAction : StatumAction { public override async DirectiveBuilder handle() throws GLib.Error { var name = "guest"; if (request.form != null) { var submitted = request.form.get_field("name"); if (submitted != null && ((!)submitted).length > 0) { name = (!)submitted; } } var is_admin = name == "admin"; var pub = new AuthPublic(); pub.name = name; pub.role = is_admin ? "admin" : "member"; pub.logout = action_registry.author(); var priv = new AuthPrivate(); priv.is_admin = is_admin; return directives() .set_private_typed("auth", Scope.SESSION, pub, priv) .navigate("/"); } } /** * `POST /_statum/action/{guid}` — logs out: clears the held `auth` slot and * redirects home. */ public class LogoutAction : StatumAction { public override async DirectiveBuilder handle() throws GLib.Error { HeldSlot auth; if (request.held.try_get("auth", out auth)) { yield state_service.clear_slot(auth.key); return directives().clear(auth.key).navigate("/"); } return directives().navigate("/"); } } /** * `POST /_statum/action/{guid}` — bumps the counter by the typed private * `delta`, using the typed {@link DirectiveBuilder.update_held} so the * `bump` action reference is preserved automatically across the update. */ public class BumpCounterAction : TypedStatumAction { public override async DirectiveBuilder handle() throws GLib.Error { var delta = request_private != null ? ((!)request_private).delta : 1; return directives().update_held("counter", c => c.value += delta); } } }