use castle_shared_parser::parse_inputs::consume_optional_separator;
use castle_tokenizer::{Tokenizable, TokenKind, extensions::{ExpectIdentifier, ExpectPunctuator, IsPunctuator}, Punctuator, Token};
use castle_types::{CastleError, Kind};
pub(crate) fn parse_kind(tokenizer: &mut impl Tokenizable) -> Result<Kind, CastleError> {
Ok(Kind {
ident: tokenizer.expect_identifier(true)?,
generics: parse_generics(tokenizer)?
})
}
pub(crate) fn parse_generics(tokenizer: &mut impl Tokenizable) -> Result<Vec<Kind>, CastleError> {
let mut generics = Vec::new();
let Token { kind, span } = tokenizer.peek_expect(true)?;
let span = span.clone();
match kind {
TokenKind::Punctuator(Punctuator::GenericOpen) => {
tokenizer.expect_punctuator(Punctuator::GenericOpen, true)?;
loop {
if tokenizer.peek_is_punctuator(Punctuator::GenericClose, true)? {
break
}
generics.push(parse_kind(tokenizer)?);
consume_optional_separator(tokenizer)?;
}
if generics.is_empty() {
return Err(CastleError::Schema("Generics <T> need at least one type argument".into(), span));
}
tokenizer.expect_punctuator(Punctuator::GenericClose, true)?;
Ok(generics)
},
_ => Ok(generics),
}
}