use crate::chars::scripts::{fmt_subscript_digits, parse_subscript_digits};
use crate::num::conversion::traits::ExactFrom;
use crate::vars::VarScheme;
use core::fmt::{Formatter, Result, Write};
fn fmt_indexed(base: char, index: usize, f: &mut Formatter) -> Result {
f.write_char(base)?;
fmt_subscript_digits(u64::exact_from(index), f)
}
fn fmt_indexed_latex(base: char, index: usize, f: &mut Formatter) -> Result {
if index < 10 {
write!(f, "{base}_{index}")
} else {
write!(f, "{base}_{{{index}}}")
}
}
fn fmt_indexed_typst(base: char, index: usize, f: &mut Formatter) -> Result {
if index < 10 {
write!(f, "{base}_{index}")
} else {
write!(f, "{base}_({index})")
}
}
fn parse_indexed(base: char, name: &str) -> Option<usize> {
usize::try_from(parse_subscript_digits(name.strip_prefix(base)?)?).ok()
}
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct IndexedVars;
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct IndexedCapsVars;
macro_rules! impl_indexed {
($t: ident, $base: expr) => {
impl VarScheme for $t {
#[inline]
fn capacity(&self) -> Option<usize> {
None
}
#[inline]
fn fmt_var(&self, index: usize, f: &mut Formatter) -> Result {
fmt_indexed($base, index, f)
}
#[inline]
fn parse_var(&self, name: &str) -> Option<usize> {
parse_indexed($base, name)
}
#[inline]
fn fmt_var_latex(&self, index: usize, f: &mut Formatter) -> Result {
fmt_indexed_latex($base, index, f)
}
#[inline]
fn fmt_var_typst(&self, index: usize, f: &mut Formatter) -> Result {
fmt_indexed_typst($base, index, f)
}
}
};
}
impl_indexed!(IndexedVars, 'x');
impl_indexed!(IndexedCapsVars, 'X');