use nom::{
bytes::complete::{tag, take_while1},
error::ErrorKind,
};
use crate::parser::{
HsmlResult, Span, advance, delimited_section_len,
error::{ErrorCode, HsmlError},
take_prefix,
};
fn is_class_delimiter(c: char) -> bool {
matches!(c, '#' | '.' | '(' | ' ' | '\t' | '\r' | '\n' | '[')
}
pub(super) fn process_class(input: Span<'_>) -> HsmlResult<'_, Span<'_>> {
let (input, _) = tag(".")(input)?;
let mut remaining = input;
let mut class_len = 0;
loop {
if let Ok((rest, taken)) =
take_while1::<_, Span, HsmlError>(|c: char| !is_class_delimiter(c))(remaining)
{
class_len += taken.fragment().len();
remaining = rest;
continue;
}
if remaining.fragment().starts_with('[') {
if let Some(len) = delimited_section_len(remaining.fragment(), '[', ']') {
class_len += len;
remaining = advance(input, class_len);
continue;
}
return Err(HsmlError::fail_code(remaining, ErrorCode::UnclosedBracket));
}
break;
}
if class_len == 0 {
return Err(HsmlError::err(input, ErrorKind::Alpha));
}
let class = take_prefix(input, class_len);
Ok((remaining, class))
}