Accept literals in attribute names (#396)
* Accept literals in attribute names * Accept literals in attribute names * Propper handling of literals in name_to_string()
This commit is contained in:
parent
d1cfde53b6
commit
8c47208568
4 changed files with 55 additions and 7 deletions
|
@ -6,6 +6,8 @@
|
||||||
[#377](https://github.com/lambda-fairy/maud/pull/377)
|
[#377](https://github.com/lambda-fairy/maud/pull/377)
|
||||||
- Implement `Render` for `Arc<T>`
|
- Implement `Render` for `Arc<T>`
|
||||||
[#380](https://github.com/lambda-fairy/maud/pull/380)
|
[#380](https://github.com/lambda-fairy/maud/pull/380)
|
||||||
|
- Accept literals in attribute names
|
||||||
|
[#396](https://github.com/lambda-fairy/maud/pull/396)
|
||||||
|
|
||||||
## [0.25.0] - 2023-04-16
|
## [0.25.0] - 2023-04-16
|
||||||
|
|
||||||
|
|
|
@ -181,6 +181,34 @@ fn hyphens_in_attribute_names() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn string_literals_in_attribute_names() {
|
||||||
|
let result = html! { this "@sentence:-is.not"="false" of-course {} };
|
||||||
|
assert_eq!(
|
||||||
|
result.into_string(),
|
||||||
|
r#"<this @sentence:-is.not="false" of-course></this>"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn raw_string_literals_in_attribute_names() {
|
||||||
|
let result = html! { this r#"@sentence:-is.not"#="false" of-course {} };
|
||||||
|
assert_eq!(
|
||||||
|
result.into_string(),
|
||||||
|
r#"<this @sentence:-is.not="false" of-course></this>"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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 {} };
|
||||||
|
assert_eq!(
|
||||||
|
result.into_string(),
|
||||||
|
r#"<this byte_string="false" 123="123" 2.5 true a="a" b="b" of-course></this>"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn class_shorthand() {
|
fn class_shorthand() {
|
||||||
let result = html! { p { "Hi, " span.name { "Lyra" } "!" } };
|
let result = html! { p { "Hi, " span.name { "Lyra" } "!" } };
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use proc_macro2::{TokenStream, TokenTree};
|
use proc_macro2::{TokenStream, TokenTree};
|
||||||
use proc_macro_error::SpanRange;
|
use proc_macro_error::SpanRange;
|
||||||
|
use syn::Lit;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Markup {
|
pub enum Markup {
|
||||||
|
@ -217,5 +218,21 @@ pub fn join_ranges<I: IntoIterator<Item = SpanRange>>(ranges: I) -> SpanRange {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name_to_string(name: TokenStream) -> String {
|
pub fn name_to_string(name: TokenStream) -> String {
|
||||||
name.into_iter().map(|token| token.to_string()).collect()
|
name.into_iter()
|
||||||
|
.map(|token| {
|
||||||
|
if let TokenTree::Literal(literal) = token {
|
||||||
|
match Lit::new(literal.clone()) {
|
||||||
|
Lit::Str(str) => str.value(),
|
||||||
|
Lit::Char(char) => char.value().to_string(),
|
||||||
|
Lit::ByteStr(byte) => {
|
||||||
|
String::from_utf8(byte.value()).expect("Invalid utf8 byte")
|
||||||
|
}
|
||||||
|
Lit::Byte(byte) => (byte.value() as char).to_string(),
|
||||||
|
_ => literal.to_string(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
token.to_string()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
|
@ -702,12 +702,13 @@ impl Parser {
|
||||||
/// Parses an identifier, without dealing with namespaces.
|
/// Parses an identifier, without dealing with namespaces.
|
||||||
fn try_name(&mut self) -> Option<TokenStream> {
|
fn try_name(&mut self) -> Option<TokenStream> {
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
if let Some(token @ TokenTree::Ident(_)) = self.peek() {
|
match self.peek() {
|
||||||
self.advance();
|
Some(token @ TokenTree::Ident(_)) | Some(token @ TokenTree::Literal(_)) => {
|
||||||
result.push(token);
|
self.advance();
|
||||||
} else {
|
result.push(token);
|
||||||
return None;
|
}
|
||||||
}
|
_ => return None,
|
||||||
|
};
|
||||||
let mut expect_ident = false;
|
let mut expect_ident = false;
|
||||||
loop {
|
loop {
|
||||||
expect_ident = match self.peek() {
|
expect_ident = match self.peek() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue