use std::fmt::Write;
use tokens::{Ident, Literal, Span, TokenStream};
use crate::parse::prelude::*;
use crate::tokenize::prelude::*;
pub struct Generics {
pub tokens: TokenStream,
}
impl Parse for Generics {
fn parse(stream: &mut ParseStream) -> Result<Self, ParseError> {
let opening = stream.expect('<')?;
let mut depth = 1;
let mut tokens = opening.tokenize();
for token in stream {
if token.is('<') {
depth += 1;
} else if token.is('>') {
depth -= 1;
if depth == 0 {
tokens.write(token);
return Ok(Generics { tokens });
}
}
tokens.write(token);
}
Err(ParseError::new(
"Missing closing > for generic type declaration",
tokens.into_iter().next(),
))
}
}
impl Tokenize for Generics {
fn tokenize(self) -> TokenStream {
self.tokens
}
fn tokenize_in(self, stream: &mut TokenStream) {
stream.extend(self.tokens);
}
}
pub struct CssLabel {
pub label: String,
pub span: Span,
}
impl Parse for CssLabel {
fn parse(stream: &mut ParseStream) -> Result<Self, ParseError> {
let mut ident: Ident = stream.parse()?;
let mut label = String::new();
let span = ident.span();
write!(&mut label, "{ident}").unwrap();
while stream.allow_consume('-').is_some() {
ident = stream.parse()?;
write!(&mut label, "-{ident}").unwrap();
}
Ok(CssLabel { label, span })
}
}
impl CssLabel {
pub fn into_literal(self) -> Literal {
let mut lit = string(&self.label);
lit.set_span(lit.span().located_at(self.span));
lit
}
}