Skip to content

Commit

Permalink
feat(parser)!: block in node name position (#11)
Browse files Browse the repository at this point in the history
* Add NodeName::Block

* Edits to NodeName::Block

* Add NodeName::Block

* Edits to NodeName::Block
  • Loading branch information
gbj authored Jan 4, 2021
1 parent 4db8ff9 commit bd88b3b
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ assert_eq!(nodes[0].children[0].value_as_string().unwrap(), "hi");
- **Braced blocks are parsed as arbitrary Rust code**

```html
<{ 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" ; } />
Expand Down
21 changes: 20 additions & 1 deletion src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,23 @@ pub struct Node {
}

impl Node {
/// Returns `String` if `name` is `Some`
/// Returns `String` if `name` is `Some` and not `NodeName::Block`
pub fn name_as_string(&self) -> Option<String> {
match self.name.as_ref() {
Some(NodeName::Block(_)) => None,
Some(name) => Some(name.to_string()),
None => None,
}
}

/// Returns `ExprBlock` if `name` is `NodeName::Block(Expr::Block)`
pub fn name_as_block(&self) -> Option<ExprBlock> {
match self.name.as_ref() {
Some(NodeName::Block(Expr::Block(expr))) => Some(expr.to_owned()),
_ => None,
}
}

/// Returns `Span` if `name` is `Some`
pub fn name_span(&self) -> Option<Span> {
match self.name.as_ref() {
Expand Down Expand Up @@ -144,6 +153,9 @@ pub enum NodeName {

/// Name separated by colons, e.g. `<div on:click={foo} />`
Colon(Punctuated<Ident, Colon>),

/// Arbitrary rust code in braced `{}` blocks
Block(Expr),
}

impl NodeName {
Expand All @@ -153,6 +165,7 @@ impl NodeName {
NodeName::Path(name) => name.span(),
NodeName::Dash(name) => name.span(),
NodeName::Colon(name) => name.span(),
NodeName::Block(name) => name.span(),
}
}
}
Expand Down Expand Up @@ -180,6 +193,7 @@ impl fmt::Display for NodeName {
.map(|ident| ident.to_string())
.collect::<Vec<String>>()
.join(":"),
NodeName::Block(_) => String::from(""),
}
)
}
Expand All @@ -200,6 +214,10 @@ impl PartialEq for NodeName {
Self::Colon(other) => this == other,
_ => false,
},
Self::Block(this) => match other {
Self::Block(other) => this == other,
_ => false,
},
}
}
}
Expand All @@ -210,6 +228,7 @@ impl ToTokens for NodeName {
NodeName::Path(name) => name.to_tokens(tokens),
NodeName::Dash(name) => name.to_tokens(tokens),
NodeName::Colon(name) => name.to_tokens(tokens),
NodeName::Block(name) => name.to_tokens(tokens),
}
}
}
5 changes: 5 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,11 @@ impl Parser {
} else if input.peek2(Dash) {
self.node_name_punctuated_ident::<Dash, fn(_) -> Dash, Ident>(input, Dash)
.map(|ok| NodeName::Dash(ok))
} else if input.peek(Brace) {
let fork = &input.fork();
let value = self.block_expr(fork)?;
input.advance_to(fork);
Ok(NodeName::Block(value))
} else if input.peek(Ident::peek_any) {
let mut segments = Punctuated::new();
let ident = Ident::parse_any(input)?;
Expand Down
20 changes: 20 additions & 0 deletions tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,26 @@ fn test_path_as_tag_name() {
assert_eq!(nodes[0].name_as_string().unwrap(), "some::path");
}

#[test]
fn test_block_as_tag_name() {
let tokens = quote! {
<{some_logic(block)} />
};

let nodes = parse2(tokens).unwrap();
assert_eq!(nodes[0].name_as_block().is_some(), true);
}

#[test]
fn test_block_as_tag_name_with_closing_tag() {
let tokens = quote! {
<{some_logic(block)}>"Test"</{some_logic(block)}>
};

let nodes = parse2(tokens).unwrap();
assert_eq!(nodes[0].name_as_block().is_some(), true);
}

#[test]
fn test_dashed_attribute_name() {
let tokens = quote! {
Expand Down

0 comments on commit bd88b3b

Please sign in to comment.