Skip to main content

max / quasi

Take what moved out to makeover, and name the trait for what it does Two things, both of them the same shape: something quasi was carrying that was never quasi's. The makeover cascade. makeover-layout 0.17.0 names a control, so quasi's Act stops describing one and starts answering with one: as_layout borrows into layout::Act rather than every renderer rebuilding the parts. quasi-tui's text.rs is gone, lifted to makeover-tui 0.16.1 where the wrap is not about a described screen and every terminal consumer wanted it. Pins move together because makeover-layout carries links, so one graph holds one copy or the build fails. Render is Serves. The trait says what a host does with a description, and "render" was the webview's word for it borrowed by the two host adapters that do not render anything. render.rs is serves.rs with it. Net 163 added against 323 removed, which is the shape of a release that mostly took things away.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-08-12 19:22 UTC
Signed with PGP, not checked
Commit: 39b8df2e8c3aa2eee8146196a2bce62144983bea
Parent: 4b4444d
20 files changed, +163 insertions, -524 deletions
M Cargo.lock +16 -16
@@ -2076,15 +2076,11 @@
2076 2076
2077 2077 [[package]]
2078 2078 name = "makeover-layout"
2079 - version = "0.16.0"
2080 - source = "registry+https://github.com/rust-lang/crates.io-index"
2081 - checksum = "5d02837b5ab4db4ee5759ddf8f77965336890d4b63c6e88e15b5782c9703138d"
2079 + version = "0.17.0"
2082 2080
2083 2081 [[package]]
2084 2082 name = "makeover-touch"
2085 - version = "0.9.0"
2086 - source = "registry+https://github.com/rust-lang/crates.io-index"
2087 - checksum = "3aaa60b135b4d57395c123bb6d70a0384b80823ebc5b8959fdf056cbc5a32043"
2083 + version = "0.10.0"
2088 2084 dependencies = [
2089 2085 "makeover-geometry",
2090 2086 "makeover-layout",
@@ -2092,9 +2088,7 @@
2092 2088
2093 2089 [[package]]
2094 2090 name = "makeover-tui"
2095 - version = "0.15.0"
2096 - source = "registry+https://github.com/rust-lang/crates.io-index"
2097 - checksum = "17f9d6a744f90ad780bd7b98d8c4b1bb2c1e16116e66b9b87eaaee085975a7e1"
2091 + version = "0.16.1"
2098 2092 dependencies = [
2099 2093 "makeover",
2100 2094 "makeover-layout",
@@ -2103,9 +2097,7 @@
2103 2097
2104 2098 [[package]]
2105 2099 name = "makeover-webview"
2106 - version = "0.32.0"
2107 - source = "registry+https://github.com/rust-lang/crates.io-index"
2108 - checksum = "9ccc45dfb72ca709785ced43eb8b30644df0ef59a618aca9fc6c6ab8553c77de"
2100 + version = "0.33.0"
2109 2101 dependencies = [
2110 2102 "makeover-geometry",
2111 2103 "makeover-layout",
@@ -5159,6 +5151,14 @@
5159 5151 source = "registry+https://github.com/rust-lang/crates.io-index"
5160 5152 checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
5161 5153
5154 + [[patch.unused]]
5155 + name = "synckit-client"
5156 + version = "0.8.0"
5157 +
5158 + [[patch.unused]]
5159 + name = "synckit-config"
5160 + version = "0.2.0"
5161 +
5162 5162 [[patch.unused]]
5163 5163 name = "kberg"
5164 5164 version = "0.1.0"
@@ -5172,9 +5172,9 @@
5172 5172 version = "0.4.0"
5173 5173
5174 5174 [[patch.unused]]
5175 - name = "synckit-client"
5176 - version = "0.8.0"
5175 + name = "makeover-build"
5176 + version = "0.26.0"
5177 5177
5178 5178 [[patch.unused]]
5179 - name = "synckit-config"
5180 - version = "0.2.0"
5179 + name = "makeover-immediate"
5180 + version = "0.15.0"
M README.md +2 -2
@@ -58,7 +58,7 @@
58 58
59 59 - `crates/quasi-router/` — the host-agnostic router. The keystone.
60 60 - `crates/quasi-http/` — the seam the http-shaped hosts share: decoding,
61 - status mapping, the htmx contract, the `Render` trait.
61 + status mapping, the htmx contract, the `Serves` trait.
62 62 - `crates/quasi-axum/` — the axum host adapter.
63 63 - `crates/quasi-tauri/` — the Tauri custom-protocol host adapter.
64 64 - `crates/quasi-webview/` — the webview renderer: a screen in, an htmx document
@@ -113,7 +113,7 @@
113 113 merged routes. There is no platform branch in it, because wry hands a handler
114 114 `<scheme>://localhost/<path>` on Linux, macOS, iOS and Windows alike.
115 115
116 - Neither adapter emits markup. A `Render` implementation supplies that, because
116 + Neither adapter emits markup. A `Serves` implementation supplies that, because
117 117 both serve HTML to a webview and generating it inside one would guarantee a
118 118 second copy. `quasi-webview` is that implementation: a screen in, an htmx
119 119 document out, with the transport entering in a single function.
@@ -13,4 +13,4 @@
13 13 workspace = true
14 14
15 15 [dependencies]
16 - makeover-layout = "0.16.0"
16 + makeover-layout = "0.17.0"
@@ -14,13 +14,13 @@
14 14
15 15 [dependencies]
16 16 quasi-router = { path = "../quasi-router", version = "0.1.0" }
17 - makeover-layout = "0.16.0"
17 + makeover-layout = "0.17.0"
18 18 # The depth palette, the theme bridge and the table. Everything else this crate
19 19 # draws is written here first and lifted upstream once a second consumer wants
20 20 # it, which is the order the suite has always moved in: the constrained consumer
21 21 # finds the shape, and the shared crate takes it after it is known rather than
22 22 # before.
23 - makeover-tui = { version = "0.15.0", features = ["theme"] }
23 + makeover-tui = { version = "0.16.1", features = ["theme"] }
24 24 ratatui = { version = "0.30", default-features = false }
25 25 # `Node::Rich` carries markdown source. A terminal has no markup to hand it to,
26 26 # so it takes the runs: `render_runs` is the words with the marks that were over
@@ -15,8 +15,8 @@
15 15 [dependencies]
16 16 quasi-router = { path = "../quasi-router", version = "0.1.0" }
17 17 quasi-http = { path = "../quasi-http", version = "0.1.0" }
18 - makeover-layout = "0.16.0"
19 - makeover-webview = "0.32.0"
18 + makeover-layout = "0.17.0"
19 + makeover-webview = "0.33.0"
20 20 # `Node::Rich` carries markdown source and this is what turns it into markup.
21 21 # Sanitising comes with it, which is why the node can carry what a user typed.
22 22 #
@@ -25,7 +25,7 @@
25 25 //!
26 26 //! # What it does not own
27 27 //!
28 - //! Markup. See [`Render`], and the reason it is a parameter: the Tauri
28 + //! Markup. See [`Serves`], and the reason it is a parameter: the Tauri
29 29 //! custom-protocol adapter serves HTML to a webview too, and generating it here
30 30 //! would guarantee a second implementation.
31 31 //!
@@ -39,13 +39,13 @@
39 39 //!
40 40 //! ```no_run
41 41 //! use std::sync::Arc;
42 - //! use quasi_axum::{Adapter, Render};
42 + //! use quasi_axum::{Adapter, Serves};
43 43 //! use quasi_router::{Node, Request, Response, RouteError, Router, Screen, Slot, RegionKind};
44 44 //!
45 45 //! struct App;
46 46 //! struct Html;
47 47 //!
48 - //! impl Render for Html {
48 + //! impl Serves for Html {
49 49 //! fn screen(&self, screen: &Screen) -> String { format!("<h1>{}</h1>", screen.title) }
50 50 //! fn fragment(&self, _node: &Node) -> String { String::new() }
51 51 //! }
@@ -77,7 +77,7 @@
77 77 use quasi_http::Refusal;
78 78 use quasi_router::{Params, Response, RouteError, Router};
79 79
80 - pub use quasi_http::{DEFAULT_BODY_LIMIT, Render, htmx};
80 + pub use quasi_http::{DEFAULT_BODY_LIMIT, Serves, htmx};
81 81
82 82 /// The state one request is answered against, once it is resolved.
83 83 ///
@@ -157,7 +157,7 @@
157 157 impl<S, R> Adapter<S, R>
158 158 where
159 159 S: Send + Sync + 'static,
160 - R: Render,
160 + R: Serves,
161 161 {
162 162 /// Mount a router over this state, rendered by this renderer.
163 163 ///
@@ -196,7 +196,7 @@
196 196 /// # use quasi_router::{Outcome, Router};
197 197 /// # struct App;
198 198 /// # #[derive(Default)] struct Html { fills: std::collections::HashMap<String, String> }
199 - /// # impl quasi_axum::Render for Html {
199 + /// # impl quasi_axum::Serves for Html {
200 200 /// # fn screen(&self, _: &quasi_router::Screen) -> String { String::new() }
201 201 /// # fn fragment(&self, _: &quasi_router::Node) -> String { String::new() }
202 202 /// # }
@@ -257,7 +257,7 @@
257 257 /// # impl Store { async fn viewer(&self, _: Option<String>) -> Option<u64> { None } }
258 258 /// # struct Viewer { store: Arc<Store>, viewer: Option<u64> }
259 259 /// # #[derive(Clone, Default)] struct Html;
260 - /// # impl quasi_axum::Render for Html {
260 + /// # impl quasi_axum::Serves for Html {
261 261 /// # fn screen(&self, _: &quasi_router::Screen) -> String { String::new() }
262 262 /// # fn fragment(&self, _: &quasi_router::Node) -> String { String::new() }
263 263 /// # }
@@ -327,7 +327,7 @@
327 327 async fn serve<S, R>(context: Arc<Context<S, R>>, request: Request) -> HttpResponse
328 328 where
329 329 S: Send + Sync + 'static,
330 - R: Render,
330 + R: Serves,
331 331 {
332 332 let (parts, body) = request.into_parts();
333 333
@@ -23,7 +23,7 @@
23 23 /// A renderer that says what it was handed, so a test can read it back.
24 24 struct Spy;
25 25
26 - impl super::Render for Spy {
26 + impl super::Serves for Spy {
27 27 fn screen(&self, screen: &Screen) -> String {
28 28 format!("screen:{}", screen.title)
29 29 }
@@ -271,7 +271,7 @@
271 271 greeting: String,
272 272 }
273 273
274 - impl super::Render for PerRequest {
274 + impl super::Serves for PerRequest {
275 275 fn screen(&self, screen: &Screen) -> String {
276 276 format!("{}:{}", self.greeting, screen.title)
277 277 }
@@ -386,7 +386,7 @@
386 386 // The adapter adds nothing to the document and removes nothing from it.
387 387 // Anything it wanted to add would be a second party emitting markup, which
388 388 // is the thing `quasi_http::render`'s existence rules out.
389 - use quasi_http::Render as _;
389 + use quasi_http::Serves as _;
390 390 assert_eq!(
391 391 served,
392 392 quasi_webview::Webview::under("/static").screen(&real_screen())
@@ -406,7 +406,7 @@
406 406 seen: String,
407 407 }
408 408
409 - impl super::Render for Viewed {
409 + impl super::Serves for Viewed {
410 410 fn screen(&self, screen: &Screen) -> String {
411 411 format!("{}|{}", self.seen, screen.title)
412 412 }