use super::{
flags::{FromTokenFlags, IntoTokensFlags},
stream::{ParseError, TokenStream},
token::{Token, VowelForm},
token_list::TokenList,
};
use std::str::FromStr;
pub trait IntoVowelForm: Sized {
fn into_vowel_form(self) -> VowelForm;
}
pub trait IntoVxCs: Sized {
fn into_vx_cs(&self) -> (VowelForm, Token);
}
pub trait FromToken: Sized {
fn from_token(token: &Token) -> Option<Self>;
}
pub trait IntoToken: Sized {
fn into_token(self) -> Token;
}
pub trait FromTokens: Sized {
fn parse_volatile(stream: &mut TokenStream, flags: FromTokenFlags) -> Result<Self, ParseError>;
fn parse(stream: &mut TokenStream, flags: FromTokenFlags) -> Result<Self, ParseError> {
let start = stream.start;
let end = stream.end;
match Self::parse_volatile(stream, flags) {
Ok(value) => Ok(value),
Err(error) => {
stream.start = start;
stream.end = end;
Err(error)
}
}
}
fn parse_str(source: &str, flags: FromTokenFlags) -> Result<Self, ParseError> {
let list = TokenList::from_str(source)?;
let mut stream = list.stream();
let result = Self::parse_volatile(&mut stream, flags)?;
if stream.is_done() {
Ok(result)
} else {
Err(ParseError::TooManyTokens)
}
}
}
pub trait IntoTokens {
fn append_tokens_to(&self, list: &mut TokenList, flags: IntoTokensFlags);
fn into_tokens(&self, flags: IntoTokensFlags) -> TokenList {
let mut list = TokenList::new();
self.append_tokens_to(&mut list, flags);
list
}
fn to_string_with(&self, flags: IntoTokensFlags) -> String {
self.into_tokens(flags).to_string()
}
}
impl<T: IntoVowelForm> IntoToken for T {
fn into_token(self) -> Token {
Token::V(self.into_vowel_form())
}
}
impl<T: Clone + IntoToken> IntoTokens for T {
fn append_tokens_to(&self, list: &mut TokenList, _flags: IntoTokensFlags) {
list.push(self.clone().into_token());
}
}