#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Style {
pub id: usize,
pub size: usize,
pub cramped: bool,
}
impl Style {
#[must_use]
pub const fn new(id: usize, size: usize, cramped: bool) -> Self {
Self { id, size, cramped }
}
#[must_use]
pub const fn sup(&self) -> &'static Self {
&STYLES[SUP[self.id]]
}
#[must_use]
pub const fn sub(&self) -> &'static Self {
&STYLES[SUB[self.id]]
}
#[must_use]
pub const fn frac_num(&self) -> &'static Self {
&STYLES[FRAC_NUM[self.id]]
}
#[must_use]
pub const fn frac_den(&self) -> &'static Self {
&STYLES[FRAC_DEN[self.id]]
}
#[must_use]
pub const fn cramp(&self) -> &'static Self {
&STYLES[CRAMP[self.id]]
}
#[must_use]
pub const fn text(&self) -> &'static Self {
&STYLES[TEXT_LOOKUP[self.id]]
}
#[inline]
#[must_use]
pub const fn is_tight(&self) -> bool {
self.size >= 2
}
}
const D: usize = 0;
const DC: usize = 1;
const T: usize = 2;
const TC: usize = 3;
const S: usize = 4;
const SC: usize = 5;
const SS: usize = 6;
const SSC: usize = 7;
const STYLES: [Style; 8] = [
Style::new(D, 0, false), Style::new(DC, 0, true), Style::new(T, 1, false), Style::new(TC, 1, true), Style::new(S, 2, false), Style::new(SC, 2, true), Style::new(SS, 3, false), Style::new(SSC, 3, true), ];
const SUP: [usize; 8] = [S, SC, S, SC, SS, SSC, SS, SSC];
const SUB: [usize; 8] = [SC, SC, SC, SC, SSC, SSC, SSC, SSC];
const FRAC_NUM: [usize; 8] = [T, TC, S, SC, SS, SSC, SS, SSC];
const FRAC_DEN: [usize; 8] = [TC, TC, SC, SC, SSC, SSC, SSC, SSC];
const CRAMP: [usize; 8] = [DC, DC, TC, TC, SC, SC, SSC, SSC];
const TEXT_LOOKUP: [usize; 8] = [D, DC, T, TC, T, TC, T, TC];
pub const DISPLAY: &Style = &STYLES[D];
pub const TEXT: &Style = &STYLES[T];
pub const SCRIPT: &Style = &STYLES[S];
pub const SCRIPTSCRIPT: &Style = &STYLES[SS];
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_style_creation() {
let style = Style::new(0, 0, false);
assert_eq!(style.id, 0);
assert_eq!(style.size, 0);
assert!(!style.cramped);
}
#[test]
fn test_superscript() {
assert_eq!(DISPLAY.sup().id, S);
assert_eq!(TEXT.sup().id, S);
assert_eq!(SCRIPT.sup().id, SS);
}
#[test]
fn test_subscript() {
assert_eq!(DISPLAY.sub().id, SC);
assert_eq!(TEXT.sub().id, SC);
assert_eq!(SCRIPT.sub().id, SSC);
}
#[test]
fn test_fraction_numerator() {
assert_eq!(DISPLAY.frac_num().id, T);
assert_eq!(TEXT.frac_num().id, S);
assert_eq!(SCRIPT.frac_num().id, SS);
}
#[test]
fn test_fraction_denominator() {
assert_eq!(DISPLAY.frac_den().id, TC);
assert_eq!(TEXT.frac_den().id, SC);
assert_eq!(SCRIPT.frac_den().id, SSC);
}
#[test]
fn test_cramp() {
assert_eq!(DISPLAY.cramp().id, DC);
assert_eq!(TEXT.cramp().id, TC);
assert_eq!(SCRIPT.cramp().id, SC);
}
#[test]
fn test_text() {
assert_eq!(DISPLAY.text().id, D);
assert_eq!(TEXT.text().id, T);
assert_eq!(SCRIPT.text().id, T);
}
#[test]
fn test_is_tight() {
assert!(!DISPLAY.is_tight());
assert!(!TEXT.is_tight());
assert!(SCRIPT.is_tight());
assert!(SCRIPTSCRIPT.is_tight());
}
}