Crates.io | syn-rsx |
lib.rs | syn-rsx |
version | 0.9.0 |
source | src |
created_at | 2020-05-29 11:02:58.597494 |
updated_at | 2022-11-10 13:36:05.363874 |
description | syn-powered parser for JSX-like TokenStreams |
homepage | |
repository | https://github.com/stoically/syn-rsx |
max_upload_size | |
id | 247331 |
size | 63,347 |
syn
-powered parser for JSX-like TokenStream
s, aka RSX. The parsed result is a nested Node
structure, similar to the browser DOM, where node name and value are syn expressions to support building proc macros.
use std::convert::TryFrom;
use eyre::bail;
use quote::quote;
use syn_rsx::{parse2, Node, NodeAttribute, NodeElement, NodeText};
// Create HTML `TokenStream`.
let tokens = quote! { <hello world>"hi"</hello> };
// Parse the tokens into a tree of `Node`s.
let nodes = parse2(tokens)?;
// Extract some specific nodes from the tree.
let Node::Element(element) = &nodes[0] else { bail!("element") };
let Node::Attribute(attribute) = &element.attributes[0] else { bail!("attribute") };
let Node::Text(text) = &element.children[0] else { bail!("text") };
// Work with the nodes.
assert_eq!(element.name.to_string(), "hello");
assert_eq!(attribute.key.to_string(), "world");
assert_eq!(String::try_from(&text.value)?, "hi");
You might want to check out the html-to-string-macro example as well.
Not opinionated
Every tag or attribute name is valid
<hello world />
Text nodes
Support for unquoted text is planned.
<div>"String literal"</div>
Node names separated by dash, colon or double colon
<tag-name attribute-key="value" />
<tag:name attribute:key="value" />
<tag::name attribute::key="value" />
Node names with reserved keywords
<input type="submit" />
Doctypes, Comments and Fragments
<!DOCTYPE html>
<!-- "comment" -->
<></>
Braced blocks are parsed as arbitrary Rust code
<{ let block = "in node name position"; } />
<div>{ let block = "in node position"; }</div>
<div { let block = "in attribute position"; } />
<div key={ let block = "in attribute value position"; } />
Attribute values can be any valid syn expression without requiring braces
<div key=some::value() />
Helpful error reporting out of the box
error: open tag has no corresponding close tag and is not self-closing
--> examples/html-to-string-macro/tests/lib.rs:5:24
|
5 | html_to_string! { <div> };
| ^^^
Customization
A ParserConfig
to customize parsing behavior is available, so if you have
slightly different requirements for parsing and it's not yet customizable
feel free to open an issue or pull request to extend the configuration.
One highlight with regards to customization is the transform_block
configuration, which takes a closure that receives raw block content as
ParseStream
and lets you optionally convert it to a TokenStream
. That makes it
possible to have custom syntax in blocks. More details in #9