Expand description
Replacement for the yew html
macro
with more Rust-idiomatic, editor-friendly syntax.
The syntax used in this crate is largely inspired by kotlinx.html and horrorshow.
Example
use defy::defy;
struct Datum {
field: &'static str,
display: bool,
label: Label,
}
enum Label {
First(i32),
Second(u64),
}
let data = vec![
Datum { field: "foo", display: false, label: Label::First(1) },
Datum { field: "bar", display: true, label: Label::Second(2) },
];
let vnode = defy! {
h1 {
+ "Hello world";
}
ul {
for datum in data {
let field = datum.field;
if datum.display {
li(data-length = field.len().to_string()) {
+ field;
}
}
match datum.label {
Label::First(i) if i > 3 => {
h2 { +i; }
}
Label::Second(i) => {
h3 { +i; }
br;
}
_ => { +"unmatched"; }
}
}
}
};
let vnode_html = /* omitted implementation rendering vnode into HTML string */;
assert_eq!(
canonicalize(vnode_html.as_str()),
canonicalize(
r#"
<h1>Hello world</h1>
<ul>
unmatched
<li data-length="3">bar</li>
<h3>2</h3>
<br> <!-- we actually emitted <br/> here, but yew processed it into <br> -->
</ul>
"#
)
);
fn canonicalize(string: &str) -> String {
// Omitted implementation: strips whitespaces and comments
}
Reference
HTML tag without children
foo(a = b, c = d);
becomes
<foo a={b} c={d} />
HTML tag with children
foo(a = b, c = d) { ... }
becomes
<foo a={b} c={d}> ... </foo>
Text values
+ expr;
becomes
`{ expr }`
Local variables
Local variables can be defined in the form of normal let
statements.
However they must precede all non-let
statements in a {}
block
in order to preserve evaluation order.
If executing a let
statement after other contents is really necessary,
place them under a separate if true {}
block.
If, If-else, For
Same as the normal Rust syntax, except the contents in braces are automatically defy!
-ed.
Match
Same as the normal Rust syntax, except match arm bodies must be surrounded in braces,
and the contents inside are automatically defy!
-ed.
Macros
- See crate-level documentation.