Skip to content

Backcountry packing - #3

Draft
nickagliano wants to merge 11 commits into
ratatui:mainfrom
nickagliano:backcountry-packing
Draft

nickagliano wants to merge 11 commits into
ratatui:mainfrom
nickagliano:backcountry-packing

Conversation

@nickagliano

Copy link
Copy Markdown

Hi!

Feel free to tear this thing apart and pick and choose what's valuable.

I am not a rust nor ratatui nor rustlings expert, but thought that this might work for the first couple of lessons.

Ratatui is going to be going on a backcountry adventure and doing some cooking outside of the kitchen, in the great outdoors.

I thought that it would be nice to give the student an experience of learning ratatui, inside of ratatui. So that was really my focus. Trying to figure out how to have a good rendering-the-lesson-in-terminal, letting them keep that open as they edit the lesson, giving them some feedback there, etc. etc.

One things that I think I need feedback on—the lesson0.md, lesson1.md files have a lot of stuff in them that might distract a student learning ratatui. The preamble, the fn app, ... then the tests that verify the user's input. Not sure what the right balance of abstraction / "hiding" stuff from the user, v.s. letting them see how the sausage gets made? It might be nice to let them see, so they can do some tangential learning?

Anyway, this is my first pass, let me know what you think. I will have some more time later today probably to fill out this PR description more.

Hopefully this can be a good place to start conversations about how we want to structure this learning harness, though!

The section opened straight into Layout/Constraint, which made the
student's first contact with Ratatui a file full of Layout, Constraint,
Block, Rect, Frame and TestBackend at once.

pack1 now ships rendering a bare `Block::new()`, which draws nothing at
all: run it and the screen is empty. Fixing it means reaching for
`Block::bordered()` and a title, which teaches `render_widget`,
`frame.area()` and what a Block is. It starts wrong rather than
incomplete, so the exercise is runnable from the first moment and the
empty screen is an honest consequence of the code that's there.

pack2 is the original Layout/Constraint exercise, unchanged.

Neither exercise uses `todo!()`: every placement of it costs 2-3
warnings before the student writes a line, and it panics, so a rendering
exercise would show nothing when run.
Rustlings validates exercises by running `cargo test`, which works fine
for TUI code (`TestBackend` + `assert_buffer_lines`), but gives the
student no way to *look* at the app they're building. This adds a viewer
for that, without changing anything about how rustlings works.

The viewer draws the exercise's `render` into an off-screen `TestBackend`
and copies the cells into a frame it controls. Full style fidelity: it's
a cell copy, not a re-serialisation, and needs no new dependency.

Design notes:

- The canvas is the entire terminal, always. Chrome floats on top with
  `Clear` rather than splitting the layout, because a panel that stole
  columns would make the canvas narrower than the real terminal — and
  for exercises teaching `Constraint`, that's a preview that lies about
  available space.
- Exactly one reserved chord (`Ctrl-G`) hands focus between the exercise
  and ratlings. An event-handling exercise legitimately wants `q`, `Esc`
  and the arrows, so the viewer must not swallow them. `Ctrl-G` also
  avoids tmux's `Ctrl-B` and screen's `Ctrl-A`.
- The label is drawn with `border_style`/`title_style`, not `.fg()` on
  the block, which would repaint every cell of the exercise underneath.
- `?` shells out to `cargo test` off-thread and surfaces the exercise
  author's own assertion messages.

It is a viewer, not a runner: progression, validation and hints stay
with rustlings.

The only thing an exercise has to expose is `pub fn render`. Note that
`pub` on a function returning a value trips clippy's
`must_use_candidate` under pedantic, and solutions are checked with
`-D warnings`, so `compartments` deliberately stays private.

`src/main.rs` is picked up by Cargo's target auto-discovery, so it
coexists with the exercise bins and survives `rustlings dev update`,
which only regenerates the contents of the `bin` list.
…i tutorial, move to next lesson in ratatui UI
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant