[rust] Rust CODE panel: the JS pane shape, with Compile and a Log split #41

Open
sleepy wants to merge 7 commits from task/39-rust-panel-ux into main
Owner

Reworks the T6-2 panel (PR #39) into the shape sleepy asked for - the JS CODE pane layout: a slim status line, the button row (Save As / Load / Compile / Run / Stop / Log / Reload), a full-height source editor, and a Log toggle that splits it horizontally with the run/build log on the bottom half.

Two commits:

  1. al serve: POST /save - the write half of /compile without the build. Save As is real: it writes the editor to the crate's src/main.rs (same source lock as compile, empty-source refusal, allow-list, loopback guard, remembered crate). 3 new Rust tests.
  2. the panel rework - new partial + CSS (a column, not two panes) + the three new button handlers. The partial's two invariants hold: it interpolates nothing and carries no ids.

Verified: 211/211 node tests, Rust gate green. Live in the game now (staged in the main checkout + new al serve on :8192) - in-game screenshots of the panel closed and Log-open are in the thread; Save As/Load exercised against a real crate, and hello's main.rs was restored after the truncating test save.

Reworks the T6-2 panel (PR #39) into the shape sleepy asked for - the JS CODE pane layout: a slim status line, the button row (Save As / Load / **Compile** / Run / Stop / **Log** / Reload), a full-height source editor, and a Log toggle that splits it horizontally with the run/build log on the bottom half. Two commits: 1. **al serve: POST /save** - the write half of /compile without the build. Save As is real: it writes the editor to the crate's src/main.rs (same source lock as compile, empty-source refusal, allow-list, loopback guard, remembered crate). 3 new Rust tests. 2. **the panel rework** - new partial + CSS (a column, not two panes) + the three new button handlers. The partial's two invariants hold: it interpolates nothing and carries no ids. Verified: 211/211 node tests, Rust gate green. Live in the game now (staged in the main checkout + new al serve on :8192) - in-game screenshots of the panel closed and Log-open are in the thread; Save As/Load exercised against a real crate, and hello's main.rs was restored after the truncating test save.
The page's Save As button needs the editor's text on <crate>/src/main.rs
without the seconds a cargo build costs for a save, and without a failed
build being the answer to "I just want to keep this".

/save is /compile's write half: it takes the same source lock (a save and
a compile of one crate cannot interleave their writes), it refuses an
empty source for the same reason the page refuses an empty Compile (an
empty write truncates the crate), and it is a crate intention, so an
unnamed /run afterwards names what was just saved — and, having built
nothing, builds it. The 404 endpoint list, the method guard, and the
loopback rule all learn the new route; three tests pin the behaviour
(write-without-build + the /run that follows, the empty refusal that
leaves the crate's file untouched, the unlisted-crate refusal that writes
nothing).
Rust CODE panel: the JS pane's shape, with Compile and a Log split
Some checks are pending
Code Quality / prettier (push) Waiting to run
Code Quality / prettier (pull_request) Waiting to run
58279af2d3
sleepy: 'the rust one should mostly mimic the js one, with the save as etc
button on top (but an extra compile button), and maybe a log button that
splits (horizontally) the code area with the bottom half being the compiler
log. but one needs a decently big text area to actually write the code,
same as the js one does it.'

The old layout was a status box, a settings row, and two side-by-side
panes — the source crammed into a 340px column while the log had equal
width, so there was no room to write code and the panel read as settings,
not editor. The new layout is the JS CODE pane's shape:

  status line (slim, one row: dot + title + detail)
  control bar: endpoint + crate fields, then the button row
              Save As · Load · Compile · Run · Stop · Log · Reload
  source editor, filling the rest of the column
  (Log pressed) a horizontal split, bottom half = the run/build log

* Save As is real, not a label: POST /save (the /save commit) writes the
  editor's text to <crate>/src/main.rs without building. The JS pane's
  Save As stores a code slot; the Rust pane's stores the file the next
  Compile builds. Load re-reads that file (the same GET /source as the
  crate select), refused while the box holds unsaved edits, for the same
  reason the select is.
* Log is a toggle on the editor, not a second pane: the Log button flips
  the logwrap's hidden state (aria-expanded is what a screen reader and a
  test both read). It is deliberately out of the busy-disabled list — a
  player who starts a Compile wants to watch the log appear.
* The editor keeps the old textarea's behaviour (text-only entry, dirty
  marker, refuse-on-empty Compile, crate-switch guard); only its box grew.

The partial still interpolates nothing and still carries no ids — the
same two invariants its tests pin — so the escaping guarantee and the
two-panels-on-one-page rule are unchanged. The two test files learn the
new hooks and the third els.source.value = assignment (the manual Load,
from parsed JSON, like the other two). 211/211 node tests; Rust gate
green.
sleepy force-pushed task/39-rust-panel-ux from 58279af2d3
Some checks are pending
Code Quality / prettier (push) Waiting to run
Code Quality / prettier (pull_request) Waiting to run
to 89489ea5a3
Some checks are pending
Code Quality / prettier (push) Waiting to run
Code Quality / prettier (pull_request) Waiting to run
2026-09-24 15:27:32 +02:00
Compare
rust: PLAN/PROGRESS — T6-2b panel rework (#40, PR #41)
Some checks are pending
Code Quality / prettier (push) Waiting to run
Code Quality / prettier (pull_request) Waiting to run
adde449b0c
sleepy's second pass on the rework:
- Run and Stop merge into one state-driven button (the JS CODE pane's Engage
  shape): it reads the running state the /status poll maintains, so it says
  "Run" and posts /run while nothing is up, and "Stop" and posts /stop while
  a child is. A child that exits on its own flips it back before the next click.
- The freed slot is an Expand button: it hides the chrome (the status line +
  the endpoint/crate fields) so the editor owns the whole column, and flips
  to Shrink. Layout, not a request, so it stays live during a busy build.
- The source editor font goes 15px -> 18px (log 15px -> 16px): code is written
  here, and readable beats dense.
The partial keeps both invariants (interpolates nothing, no ids); the new
hooks are panel/run-stop/expand. Tests: the protocol test now drives the merged
button and reads its label to know which request to expect, and its stubs move
the way the endpoint does (/run sets running, /stop clears it). 211/211.
rust: PLAN/PROGRESS — T6-2b second pass (Run/Stop merge, Expand, font)
Some checks are pending
Code Quality / prettier (push) Waiting to run
Code Quality / prettier (pull_request) Waiting to run
066624963c
Rust CODE panel: syntax highlighting — the editor is now CodeMirror in the Rust mode
Some checks are pending
Code Quality / prettier (push) Waiting to run
Code Quality / prettier (pull_request) Waiting to run
8cc580a4cd
sleepy: "can be a tad bigger, but it works. now, syntax highlighting."

The RUST pane's editor is a CodeMirror instance in the Rust mode — the same
library and pixel theme the JS CODE pane already uses, so Rust highlights the
way the JS editor does.

- js/rust_code_panel.js: the editor's text gets one read (editor_text) and one
  write (set_editor_text). The write is textarea.value on the fallback and
  CodeMirror.setValue on the instance (a value, not markup), so the page's
  escaping guarantee is unchanged: source still reaches the DOM only as a text
  property from parsed JSON. mount_editor() (called from start(), before the
  first /source) swaps the textarea for the instance in place — the same
  CodeMirror(function(place){…}, options) shape code_logic() uses — and degrades
  to the plain textarea on any host without CodeMirror (the dependency-free
  test DOM, the no_html shell), which is how the fallback stays exercised.
- js/codemirror/5.65.1/rust.js: the vendored CodeMirror build is core-only (no
  addon/mode/simple.js), so the official Rust simple mode registered nothing
  and the first pass rendered uncoloured. This is that official 5.65.1 mode
  ported to a self-contained CodeMirror.defineMode: same token classes (so
  pixel.css colours them), the string/raw-string/comment states, a def flag so
  `fn main` / `let mut x` colour the name, and a brace-depth indent.
- htmls/index.html + htmls/rust_code.html: load the Rust mode (both hosts get
  highlighting); css: the .CodeMirror editor takes the textarea's slot, border
  and code background, and the source font goes 18px -> 19px.
- tests: the two "source reaches the DOM as a text property" pins now assert the
  one fallback write + one instance write through the one door (set_editor_text),
  and a new test drives the client with a fake CodeMirror and pins that the
  source reaches the *instance* as a value and the dirty marker follows it.
  211 -> 212 node tests.

Verified: 212/212 node; Rust gate untouched (frontend only); live headless shot
shows `use`/`const` keywords, `std`/`env` variables, `u64`/`f64` atoms and
comments coloured, in-game.
sleepy force-pushed task/39-rust-panel-ux from 8cc580a4cd
Some checks are pending
Code Quality / prettier (push) Waiting to run
Code Quality / prettier (pull_request) Waiting to run
to 1cc350e2bc
Some checks failed
Code Quality / prettier (push) Has been cancelled
Code Quality / prettier (pull_request) Has been cancelled
2026-09-25 14:58:49 +02:00
Compare
Some checks failed
Code Quality / prettier (push) Has been cancelled
Code Quality / prettier (pull_request) Has been cancelled
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin task/39-rust-panel-ux:task/39-rust-panel-ux
git switch task/39-rust-panel-ux

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff task/39-rust-panel-ux
git switch task/39-rust-panel-ux
git rebase main
git switch main
git merge --ff-only task/39-rust-panel-ux
git switch task/39-rust-panel-ux
git rebase main
git switch main
git merge --no-ff task/39-rust-panel-ux
git switch main
git merge --squash task/39-rust-panel-ux
git switch main
git merge --ff-only task/39-rust-panel-ux
git switch main
git merge task/39-rust-panel-ux
git push origin main
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sleepy/adventureland_mongodb!41
No description provided.