Skip to main content

max / quasi

Describe a chart, and fix the loop window that hid a guard A chart is `Node::Chart { axis, bars }`: the bars are the run a request varies the length of and the axis is one fact beside it, which is a loop and a hole outside it. Drawn by all three renderers through a makeover widget each, the way a meter already is. `Tag::latched` takes no argument now, and a condition is written as a guard. A `bool` has no stand-in and a loop body cannot carry "exactly one of these differs" as a value -- the Select's problem, with the Select's answer. It joins `chosen`, `figure` and `bar` in `PLACED`: what it varies is a class inside the tag its own statement produces, so turning it off deletes bytes. Breaking; every call site in the tree moves with it. `grown` converted both ends of its window by subtracting a body length. `wide` is `P F F Q` and the removable copy sits anywhere from `|P|` to `|P| + |F|`; the latest of those is one copy after the body's own place, but the earliest already IS that place and does not move. Subtracting from both underflowed -- fixed in 0.108 by answering `at`, which left a window one point wide, and that is the second failure: `placed` then has nowhere to slide to. Which matters because the prefix scan can run past the body. `</div>` and `<div class="figure"` share their `<`, so the converted `at` lands a byte inside an opening tag, and with no window the loop sat off its own body and overlapped a guard inside it. `build` refused the screen as a structure that is not a tree. Every loop already on the seam happened to have an unguarded body, which is why nothing had hit it. `quasi-bench`: `charted` proves the member derives, replays and fills byte for byte across every shape the data takes; `guarded` is the regression test for the window, on a shape as ordinary as a strip of figures where each may report a change.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session
https://claude.ai/code/session_01P8ostB2UmZJGj5WjSHRSot
Author: Max Johnson <me@maxj.phd> · 2026-09-08 18:13 UTC
Signed with PGP, not checked
Commit: cceb9681f9ee3985ae13131917f6442dd4fb5122
Parent: 6413816
25 files changed, +770 insertions, -73 deletions
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "quasi-axum"
3 - version = "0.108.0"
3 + version = "0.109.0"
4 4 description = "The axum host adapter for quasi-router: an HTTP request in, a rendered description out"
5 5 edition.workspace = true
6 6 rust-version.workspace = true
@@ -13,14 +13,14 @@
13 13 workspace = true
14 14
15 15 [dependencies]
16 - quasi-router = { path = "../quasi-router", version = "0.108" }
17 - quasi-http = { path = "../quasi-http", version = "0.108" }
16 + quasi-router = { path = "../quasi-router", version = "0.109" }
17 + quasi-http = { path = "../quasi-http", version = "0.109" }
18 18 axum = "0.8.8"
19 19 http = "1.3.1"
20 20 tokio = { version = "1.50.0", features = ["rt"] }
21 21
22 22 [dev-dependencies]
23 - quasi-webview = { path = "../quasi-webview", version = "0.108" }
23 + quasi-webview = { path = "../quasi-webview", version = "0.109" }
24 24 tokio = { version = "1.50.0", features = ["macros", "rt-multi-thread"] }
25 25 tower = { version = "0.5.3", features = ["util"] }
26 26 http-body-util = "0.1.3"
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "quasi-basics"
3 - version = "0.108.0"
3 + version = "0.109.0"
4 4 description = "The first-party widget set: named assemblies of primitives, shared across our apps"
5 5 edition.workspace = true
6 6 rust-version.workspace = true
@@ -13,7 +13,7 @@
13 13 workspace = true
14 14
15 15 [dependencies]
16 - quasi-router = { path = "../quasi-router", version = "0.108" }
16 + quasi-router = { path = "../quasi-router", version = "0.109" }
17 17 quasi-declare = { path = "../quasi-declare", version = "0.1" }
18 18 makeover-layout = "0.44"
19 19
@@ -21,5 +21,5 @@
21 21 # A widget's guarantees are claims about what a renderer draws, so they are
22 22 # tested against a real one rather than by walking the tree the assembly just
23 23 # built. The webview is the renderer that recognises names today.
24 - quasi-webview = { path = "../quasi-webview", version = "0.108" }
25 - quasi-http = { path = "../quasi-http", version = "0.108" }
24 + quasi-webview = { path = "../quasi-webview", version = "0.109" }
25 + quasi-http = { path = "../quasi-http", version = "0.109" }
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "quasi-bench"
3 - version = "0.108.0"
3 + version = "0.109.0"
4 4 description = "What a described screen costs to render, in time and in allocations"
5 5 edition.workspace = true
6 6 rust-version.workspace = true
@@ -26,14 +26,14 @@
26 26 askama = ["dep:askama"]
27 27
28 28 [dependencies]
29 - quasi-router = { path = "../quasi-router", version = "0.108" }
30 - quasi-webview = { path = "../quasi-webview", version = "0.108" }
31 - quasi-tui = { path = "../quasi-tui", version = "0.108" }
32 - quasi-immediate = { path = "../quasi-immediate", version = "0.108" }
29 + quasi-router = { path = "../quasi-router", version = "0.109" }
30 + quasi-webview = { path = "../quasi-webview", version = "0.109" }
31 + quasi-tui = { path = "../quasi-tui", version = "0.109" }
32 + quasi-immediate = { path = "../quasi-immediate", version = "0.109" }
33 33 # `Serves` is the trait carrying `screen` and `fragment`, which is what the
34 34 # webview is measured through. Taken directly rather than through quasi-webview
35 35 # because a bench calling a trait method should name the trait it calls.
36 - quasi-http = { path = "../quasi-http", version = "0.108" }
36 + quasi-http = { path = "../quasi-http", version = "0.109" }
37 37 # The macro under measurement. The bench holds the declared copy of the same
38 38 # screen `staging.rs` writes by hand, so the staged column measures what the
39 39 # server actually serves rather than a shape written for a benchmark.
@@ -52,7 +52,7 @@
52 52 # optional here: a `Context` with no font builds no galley, so a frame drawn
53 53 # without them measures layout over nothing.
54 54 egui = { version = "0.35", features = ["default_fonts"] }
55 - makeover-immediate = "0.45"
55 + makeover-immediate = "0.46"
56 56 # Allocation counting, and only that. Optional and off by default. It is here
57 57 # rather than a hand-written `GlobalAlloc` because the workspace forbids
58 58 # `unsafe_code` and `forbid` cannot be overridden per crate; see
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "quasi-declare"
3 - version = "0.1.14"
3 + version = "0.1.15"
4 4 description = "The declare! form: a screen description compiled to Rust at build time."
5 5 edition.workspace = true
6 6 rust-version.workspace = true
@@ -31,4 +31,4 @@
31 31 trybuild = "1"
32 32 # The generated code names the vocabulary, so a case that is meant to COMPILE
33 33 # needs it. A proc-macro crate cannot depend on it outside dev.
34 - quasi-router = { path = "../quasi-router", version = "0.108" }
34 + quasi-router = { path = "../quasi-router", version = "0.109" }
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "quasi-http"
3 - version = "0.108.0"
3 + version = "0.109.0"
4 4 description = "The http-shaped seam quasi's webview host adapters share: decoding in, a rendered description out"
5 5 edition.workspace = true
6 6 rust-version.workspace = true
@@ -13,6 +13,6 @@
13 13 workspace = true
14 14
15 15 [dependencies]
16 - quasi-router = { path = "../quasi-router", version = "0.108" }
16 + quasi-router = { path = "../quasi-router", version = "0.109" }
17 17 http = "1.3.1"
18 18 form_urlencoded = "1.2.2"