use std::fmt::{Display, Formatter, Write};
use crate::{
characters::{Glyph, Numeral, ZWJ},
policy::{Policy, Standard},
};
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub enum Token<P: Policy = Standard> {
Char(char),
Glyph(Glyph<P>),
Number(Numeral),
}
impl<P: Policy> Token<P> {
pub const fn change_policy<Q: Policy>(self) -> Token<Q> {
match self {
Self::Glyph(glyph) => Token::Glyph(glyph.change_policy()),
Self::Char(char) => Token::Char(char),
Self::Number(number) => Token::Number(number),
}
}
pub const fn glyph(&self) -> Option<&Glyph<P>> {
match self {
Self::Char(_) => None,
Self::Glyph(g) => Some(g),
Self::Number(_) => None,
}
}
pub const fn numeral(&self) -> Option<&Numeral> {
match self {
Self::Char(_) => None,
Self::Glyph(_) => None,
Self::Number(n) => Some(n),
}
}
}
impl<P: Policy> Display for Token<P> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::Char(ch) => f.write_char(*ch),
Self::Glyph(g) => g.fmt(f),
Self::Number(n) => n.fmt(f),
}
}
}
impl<P: Policy> FromIterator<Token<P>> for String {
fn from_iter<I: IntoIterator<Item=Token<P>>>(iter: I) -> Self {
let mut iter = iter.into_iter().peekable();
let mut buf = String::new();
while let Some(token) = iter.next() {
write!(buf, "{token}").expect("Error writing String");
if let Token::Glyph(current) = token {
if let Some(Token::Glyph(next)) = iter.peek() {
if current.ligates_with(next) {
buf.push(ZWJ);
}
}
}
}
buf
}
}