Developer Overview
This document summarizes Toboggan's architecture, main crates, core types, runtime model, and how to build and extend the project.
Project at a glance
- Multi-platform presentation system written in Rust
- Real-time synchronization via WebSockets
- Organized as a main workspace (fast build) and a separate
toboggan-desktopworkspace (heavier GPU deps)
Workspace layout
toboggan-core— Core domain types:Talk,Slide,Content,State,Command,Notification.toboggan-cli— Folder-to-presentation converter and presentation statistics tooling.toboggan-server— Axum-based WebSocket + REST server, state manager, client registry.toboggan-client— Shared WebSocket client utilities used by various clients.toboggan-tui— Terminal client based onratatuiandcrossterm.toboggan-web/toboggan-wasm— TypeScript frontend and optional WASM client.toboggan-mobile/TobogganApp— iOS/Android integration via UniFFI and SwiftUI frontend.toboggan-desktop— Separate workspace usingiced+wgpu(compiles independently).
Core concepts and types
Talk
- Container for a presentation:
title,date, optionalhead/footer, andslides: Vec<Slide>. Talk::new, builder-stylewith_date,with_footer,add_slide.
Slide and SlideId
Slidecontainskind,style,title,body,notes, and optionalterminals.SlideIdis a typed wrapper aroundusizewith helpers:FIRST,index(),prev(),display_number().
Content
- Enum representing slide content:
Empty,Text,Html { raw, alt, style }. - Helper constructors:
Content::text,Content::html,Content::html_with_alt.
Runtime State
- States:
Init,Running { current, current_step },Done { current, current_step }. - Helpers:
current(),current_step(),next(),previous(),is_first_slide(),is_last_slide(),update_slide().
Protocol: Command and Notification
Command(client→server):Register,Unregister,Ping, navigation (First,Last,GoTo,NextSlide,PreviousSlide),NextStep/PreviousStep, effects likeBlink.Notification(server→clients):State,Error,Pong,Blink,TalkChange,Registered,ClientConnected,ClientDisconnected.
Server runtime model
TobogganStatecomposesTalkServiceandClientServiceand coordinates commands and broadcasts.- WebSocket flow: clients
Register→ server sends initialState→ client exchangesCommands → serverhandle_command→ broadcastsNotifications. - Concurrency: async tasks per connection (watcher, sender, receiver, heartbeat). Shared state uses thread-safe services and channels.
CLI behavior highlights
toboggan-cliparses folders into slides, supports frontmatter TOML, progressive reveals via<!-- pause -->, speaker notes, and multiple output formats (TOML, JSON, YAML, HTML).- Provides presentation statistics and optional numbering of parts/slides.
Build & run (developer quick commands)
Backend (Rust only)
# Build main workspace (CLI + server + TUI)
cargo build
# Build server and run with example presentation
cargo run -p toboggan-server -- slides_ex/riir-flat-output.toml
# Convert a folder to a talk
cargo run -p toboggan-cli -- slides_ex/riir-flat.md -o /tmp/my-talk.toml
# Run terminal client
cargo run -p toboggan-tui -- --host localhost --port 8080
Web frontend (adds WASM + TypeScript)
cd toboggan-web/toboggan-wasm
wasm-pack build --target web --release
cd ..
npm install
npm run build
cd ..
cargo build -p toboggan-server # re-embed with updated dist
Tests, formatting and linting
- Run tests:
cargo testorcargo nextest runfor parallel execution. - Format:
cargo fmt— Lints:cargo clippy.
Where to look in code
- Core types:
toboggan-core/src/(talk.rs,slide.rs,content.rs,state.rs,command.rs,notification.rs). - CLI:
toboggan-cli/src/(main.rs,lib.rs,parser/,output/). - Server:
toboggan-server/src/(router/,services/,state.rs,watcher.rs).
Next steps and contribution ideas
- Add more examples for the WASM and mobile clients.
- Expand OpenAPI coverage (feature
openapi) to document HTTP endpoints. - Add more integration tests that run server + headless client to validate protocol.