attr valid: return whether attrs non-empty
This commit is contained in:
parent
161dfec96d
commit
b512c670e6
3 changed files with 39 additions and 16 deletions
45
src/attr.rs
45
src/attr.rs
|
@ -10,13 +10,18 @@ pub(crate) fn parse<'s, S: DiscontinuousString<'s>>(chars: S) -> Attributes<'s>
|
||||||
a
|
a
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn valid<I: Iterator<Item = char>>(chars: I) -> usize {
|
pub fn valid<I: Iterator<Item = char>>(chars: I) -> (usize, bool) {
|
||||||
|
let mut has_attr = false;
|
||||||
let mut p = Parser::new(chars);
|
let mut p = Parser::new(chars);
|
||||||
if p.any(|e| matches!(e, Element::Invalid)) {
|
for e in &mut p {
|
||||||
0
|
match e {
|
||||||
} else {
|
Element::Class(..) | Element::Identifier(..) | Element::Attribute(..) => {
|
||||||
p.pos
|
has_attr = true
|
||||||
|
}
|
||||||
|
Element::Invalid => return (0, false),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
(p.pos, has_attr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attributes are relatively rare, we choose to pay 8 bytes always and sometimes an extra
|
// Attributes are relatively rare, we choose to pay 8 bytes always and sometimes an extra
|
||||||
|
@ -357,7 +362,25 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn valid_full() {
|
fn valid_full() {
|
||||||
let src = "{.class %comment%}";
|
let src = "{.class %comment%}";
|
||||||
assert_eq!(super::valid(src.chars()), src.len());
|
assert_eq!(super::valid(src.chars()), (src.len(), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn valid_empty() {
|
||||||
|
let src = "{}";
|
||||||
|
assert_eq!(super::valid(src.chars()), (src.len(), false));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn valid_whitespace() {
|
||||||
|
let src = "{ \n }";
|
||||||
|
assert_eq!(super::valid(src.chars()), (src.len(), false));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn valid_comment() {
|
||||||
|
let src = "{%comment%}";
|
||||||
|
assert_eq!(super::valid(src.chars()), (src.len(), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -365,15 +388,15 @@ mod test {
|
||||||
let src = "{.class}";
|
let src = "{.class}";
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
super::valid(src.chars().chain("{.ignore}".chars())),
|
super::valid(src.chars().chain("{.ignore}".chars())),
|
||||||
src.len()
|
(src.len(), true),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn valid_invalid() {
|
fn valid_invalid() {
|
||||||
assert_eq!(super::valid(" {.valid}".chars()), 0);
|
assert_eq!(super::valid(" {.valid}".chars()), (0, false));
|
||||||
assert_eq!(super::valid("{.class invalid}".chars()), 0);
|
assert_eq!(super::valid("{.class invalid}".chars()), (0, false));
|
||||||
assert_eq!(super::valid("abc".chars()), 0);
|
assert_eq!(super::valid("abc".chars()), (0, false));
|
||||||
assert_eq!(super::valid("{.abc.}".chars()), 0);
|
assert_eq!(super::valid("{.abc.}".chars()), (0, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -270,7 +270,7 @@ impl BlockParser {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'{' => (attr::valid(line_t.chars()) == line_t.trim_end().len())
|
'{' => (attr::valid(line_t.chars()).0 == line_t.trim_end().len())
|
||||||
.then(|| (Block::Atom(Attributes), Span::by_len(start, line_t.len()))),
|
.then(|| (Block::Atom(Attributes), Span::by_len(start, line_t.len()))),
|
||||||
'|' => (&line_t[line_t.len() - 1..] == "|"
|
'|' => (&line_t[line_t.len() - 1..] == "|"
|
||||||
&& &line_t[line_t.len() - 2..line_t.len() - 1] != "\\")
|
&& &line_t[line_t.len() - 2..line_t.len() - 1] != "\\")
|
||||||
|
|
|
@ -239,12 +239,12 @@ impl<I: Iterator<Item = char> + Clone> Parser<I> {
|
||||||
.map_or(false, |e| e.kind == EventKind::Str)
|
.map_or(false, |e| e.kind == EventKind::Str)
|
||||||
{
|
{
|
||||||
let mut ahead = self.lexer.inner().clone();
|
let mut ahead = self.lexer.inner().clone();
|
||||||
let mut attr_len = attr::valid(std::iter::once('{').chain(&mut ahead)) - 1;
|
let mut attr_len = attr::valid(std::iter::once('{').chain(&mut ahead)).0 - 1;
|
||||||
if attr_len > 0 {
|
if attr_len > 0 {
|
||||||
while attr_len > 0 {
|
while attr_len > 0 {
|
||||||
self.lexer = lex::Lexer::new(ahead.clone());
|
self.lexer = lex::Lexer::new(ahead.clone());
|
||||||
self.span = self.span.extend(attr_len);
|
self.span = self.span.extend(attr_len);
|
||||||
attr_len = attr::valid(&mut ahead);
|
attr_len = attr::valid(&mut ahead).0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let i = self
|
let i = self
|
||||||
|
@ -345,7 +345,7 @@ impl<I: Iterator<Item = char> + Clone> Parser<I> {
|
||||||
};
|
};
|
||||||
self.openers.drain(o..);
|
self.openers.drain(o..);
|
||||||
let mut ahead = self.lexer.inner().clone();
|
let mut ahead = self.lexer.inner().clone();
|
||||||
let mut attr_len = attr::valid(&mut ahead);
|
let mut attr_len = attr::valid(&mut ahead).0;
|
||||||
if attr_len > 0 {
|
if attr_len > 0 {
|
||||||
let span_closer = self.span;
|
let span_closer = self.span;
|
||||||
self.events[e_attr].span = Span::empty_at(self.span.end());
|
self.events[e_attr].span = Span::empty_at(self.span.end());
|
||||||
|
@ -354,7 +354,7 @@ impl<I: Iterator<Item = char> + Clone> Parser<I> {
|
||||||
self.lexer = lex::Lexer::new(ahead.clone());
|
self.lexer = lex::Lexer::new(ahead.clone());
|
||||||
self.span = self.events[e_attr].span.extend(attr_len);
|
self.span = self.events[e_attr].span.extend(attr_len);
|
||||||
self.events[e_attr].span = self.span;
|
self.events[e_attr].span = self.span;
|
||||||
attr_len = attr::valid(&mut ahead);
|
attr_len = attr::valid(&mut ahead).0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if event.is_none() {
|
if event.is_none() {
|
||||||
|
|
Loading…
Reference in a new issue