use super::{FmlValue, Quote, FmlFunction};
use crate::ast::{
FunctionToken, Token,
token::{self, TokenVec},
};
use chumsky::Parser;
impl TryFrom<Token> for FmlValue {
type Error = ();
fn try_from(value: Token) -> Result<Self, Self::Error> {
Ok(match value {
Token::Linebreak => Self::Linebreak,
Token::CodeBlock { lang, body } => Self::CodeBlock { lang, body },
Token::CodeInline(s) => Self::CodeInline(s),
Token::Heading1(tokens) => Self::Heading1(TokenVec(tokens).try_into()?),
Token::Heading2(tokens) => Self::Heading2(TokenVec(tokens).try_into()?),
Token::Heading3(tokens) => Self::Heading3(TokenVec(tokens).try_into()?),
Token::SupLine(tokens) => Self::Superline(TokenVec(tokens).try_into()?),
Token::SubLine(tokens) => Self::Subline(TokenVec(tokens).try_into()?),
Token::ListItem(tokens) => Self::ListItem(TokenVec(tokens).try_into()?),
Token::Quote(s) => {
let p = crate::parser::functions::fml_values();
let tokens = p.parse(&s).into_result().map_err(|_| ())?;
let values = TokenVec(tokens).try_into()?;
Quote(values)
}
Token::CwSpoiler(tokens) => Self::ContentWarning {
reason: "Spoilers".into(),
body: TokenVec(tokens).try_into()?,
},
Token::Hyperlink { fml, uri } => Self::Hyperlink {
fml: TokenVec(fml).try_into()?,
uri,
},
Token::Bold(tokens) => Self::Bold(TokenVec(tokens).try_into()?),
Token::Italic(tokens) => Self::Italic(TokenVec(tokens).try_into()?),
Token::Strikethrough(tokens) => Self::Strikethrough(TokenVec(tokens).try_into()?),
Token::Underline(tokens) => Self::Underline(TokenVec(tokens).try_into()?),
Token::Superscript(tokens) => Self::Superscript(TokenVec(tokens).try_into()?),
Token::Subscript(tokens) => Self::Subscript(TokenVec(tokens).try_into()?),
Token::Function(FunctionToken { name, params, body }) => FmlFunction {
name,
params,
body: TokenVec(body).try_into()?,
}
.interpret(),
Token::Typst(s) => Self::Typst(s),
Token::Text(s) => Self::Text(s),
})
}
}
impl TryFrom<TokenVec> for Vec<FmlValue> {
type Error = ();
fn try_from(tokens: TokenVec) -> Result<Self, Self::Error> {
let mut vec = vec![];
for t in tokens.0 {
vec.push(t.try_into()?);
}
Ok(vec)
}
}