pub enum Html {
Text {
text: String,
hash: u64,
},
Element {
tag: String,
attrs: Vec<(String, String)>,
key: Option<String>,
children: Vec<Html>,
tag_key_h: u64,
attrs_h: u64,
children_h: u64,
},
}Variants§
Text
Element
Fields
tag_key_h: u64Three accumulators rather than one hash, so that the hash is a function of the node’s structure and not of the order the builder methods happened to be called in. Getting this wrong makes two identical subtrees hash differently, and a differ that trusts a hash it cannot reproduce is worse than one with no hash at all.
Implementations§
Source§impl Html
impl Html
pub fn text(s: impl Into<String>) -> Html
Sourcepub fn el(tag: impl Into<String>) -> Html
pub fn el(tag: impl Into<String>) -> Html
Start an element. Attributes and children are added with the builder methods below; each step costs one multiply per byte added, and nothing is ever rehashed.
pub fn attr(self, name: impl Into<String>, value: impl Into<String>) -> Html
Sourcepub fn attr_if(
self,
cond: bool,
name: impl Into<String>,
value: impl Into<String>,
) -> Html
pub fn attr_if( self, cond: bool, name: impl Into<String>, value: impl Into<String>, ) -> Html
Conditional attribute — the (if t.done "done" "") shape from the sketch, without emitting
an empty attribute the differ would then have to churn on.
Sourcepub fn on(self, event: &str, command: Value) -> Html
pub fn on(self, event: &str, command: Value) -> Html
A handler in view compiles to a declarative attribute — no user JavaScript exists in Mode
A (§5.1 “Input capture”), so script-src can stay near-empty. command is the serialised
command constructor the thin client posts back up the socket.
pub fn key(self, k: impl Into<String>) -> Html
pub fn child(self, c: Html) -> Html
pub fn children(self, cs: impl IntoIterator<Item = Html>) -> Html
Sourcepub fn rehash(&self) -> Html
pub fn rehash(&self) -> Html
Rebuild the tree, recomputing every structural hash bottom-up.
Needed after in-place surgery on a node: an edit deep in a tree invalidates the hash of every ancestor, and a stale hash is worse than no hash — the differ would skip a subtree that did change.
pub fn hash(&self) -> u64
pub fn key_of(&self) -> Option<&str>
pub fn child_at(&self, i: usize) -> Option<&Html>
Sourcepub fn node_count(&self) -> usize
pub fn node_count(&self) -> usize
Node count — the denominator of “how much of the tree did the diff actually touch”.
Sourcepub fn to_wire(&self) -> Value
pub fn to_wire(&self) -> Value
The wire encoding: a text node is a JSON string, an element is [tag, attrs, children].
Positional and terse because it rides in every patch. §4.4 specifies a field-tagged binary
encoding for Beck↔Beck traffic; the thin client is a browser, and JSON costs it zero bytes
of decoder — see crate::patch::Codec for the measured comparison.
Sourcepub fn render(&self) -> String
pub fn render(&self) -> String
Server-side render. “First paint is free SSR: evaluate pure view against the current
accumulator, ship HTML.”
Emitted without any inter-element whitespace, deliberately: patch paths are child indices, and a pretty-printer would insert text nodes that the server’s tree does not have, so the first patch after hydration would address the wrong node.