diff --git a/maud/tests/basic_syntax.rs b/maud/tests/basic_syntax.rs
index 96e0235e..c2c5dc5f 100644
--- a/maud/tests/basic_syntax.rs
+++ b/maud/tests/basic_syntax.rs
@@ -201,11 +201,19 @@ fn raw_string_literals_in_attribute_names() {
#[test]
fn other_literals_in_attribute_names() {
- let result =
- html! { this b"byte_string"="false" 123="123" 2.5 true 'a'="a" b'b'="b" of-course {} };
+ let result = html! { this r#"raw_string"#="false" 123="123" 123usize "2.5" true of-course {} };
assert_eq!(
result.into_string(),
- r#""#
+ r#""#
+ );
+}
+
+#[test]
+fn idents_and_literals_in_names() {
+ let result = html! { custom:element-001 test:123-"test"="123" .m-2.p-2 {} };
+ assert_eq!(
+ result.into_string(),
+ r#""#
);
}
diff --git a/maud/tests/warnings/non-string-literal.stderr b/maud/tests/warnings/non-string-literal.stderr
index 635617b8..7755e3f0 100644
--- a/maud/tests/warnings/non-string-literal.stderr
+++ b/maud/tests/warnings/non-string-literal.stderr
@@ -1,41 +1,29 @@
-error: literal must be double-quoted: `"42"`
- --> $DIR/non-string-literal.rs:5:9
- |
-5 | 42
- | ^^
-
-error: literal must be double-quoted: `"42usize"`
- --> $DIR/non-string-literal.rs:6:9
- |
-6 | 42usize
- | ^^^^^^^
-
error: literal must be double-quoted: `"42.0"`
- --> $DIR/non-string-literal.rs:7:9
+ --> tests/warnings/non-string-literal.rs:7:9
|
7 | 42.0
| ^^^^
error: literal must be double-quoted: `"a"`
- --> $DIR/non-string-literal.rs:8:9
+ --> tests/warnings/non-string-literal.rs:8:9
|
8 | 'a'
| ^^^
error: expected string
- --> $DIR/non-string-literal.rs:9:9
+ --> tests/warnings/non-string-literal.rs:9:9
|
9 | b"a"
| ^^^^
error: expected string
- --> $DIR/non-string-literal.rs:10:9
+ --> tests/warnings/non-string-literal.rs:10:9
|
10 | b'a'
| ^^^^
error: attribute value must be a string
- --> $DIR/non-string-literal.rs:13:24
+ --> tests/warnings/non-string-literal.rs:13:24
|
13 | input disabled=true;
| ^^^^
@@ -44,7 +32,7 @@ error: attribute value must be a string
= help: to toggle the attribute, use square brackets: `disabled[some_boolean_flag]`
error: attribute value must be a string
- --> $DIR/non-string-literal.rs:14:24
+ --> tests/warnings/non-string-literal.rs:14:24
|
14 | input disabled=false;
| ^^^^^
diff --git a/maud_macros/src/parse.rs b/maud_macros/src/parse.rs
index 662b8309..1b85d1f3 100644
--- a/maud_macros/src/parse.rs
+++ b/maud_macros/src/parse.rs
@@ -204,7 +204,13 @@ impl Parser {
}
// Boolean literals are idents, so `Lit::Bool` is handled in
// `markup`, not here.
- Lit::Int(..) | Lit::Float(..) => {
+ Lit::Int(lit_int) => {
+ return ast::Markup::Literal {
+ content: lit_int.to_string(),
+ span: SpanRange::single_span(literal.span()),
+ };
+ }
+ Lit::Float(..) => {
emit_error!(literal, r#"literal must be double-quoted: `"{}"`"#, literal);
}
Lit::Char(lit_char) => {
@@ -702,27 +708,32 @@ impl Parser {
/// Parses an identifier, without dealing with namespaces.
fn try_name(&mut self) -> Option {
let mut result = Vec::new();
- match self.peek() {
- Some(token @ TokenTree::Ident(_)) | Some(token @ TokenTree::Literal(_)) => {
- self.advance();
- result.push(token);
- }
- _ => return None,
- };
- let mut expect_ident = false;
+ let mut expect_ident_or_literal = true;
loop {
- expect_ident = match self.peek() {
+ expect_ident_or_literal = match self.peek() {
Some(TokenTree::Punct(ref punct)) if punct.as_char() == '-' => {
self.advance();
result.push(TokenTree::Punct(punct.clone()));
true
}
- Some(TokenTree::Ident(ref ident)) if expect_ident => {
+ Some(token @ TokenTree::Ident(_)) if expect_ident_or_literal => {
self.advance();
- result.push(TokenTree::Ident(ident.clone()));
+ result.push(token);
false
}
- _ => break,
+ Some(TokenTree::Literal(ref literal)) if expect_ident_or_literal => {
+ self.literal(literal.clone());
+ self.advance();
+ result.push(TokenTree::Literal(literal.clone()));
+ false
+ }
+ _ => {
+ if result.is_empty() {
+ return None;
+ } else {
+ break;
+ }
+ }
};
}
Some(result.into_iter().collect())