use std::ops::Range;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum EnvKind {
Known(KnownEnv),
Custom(Range<usize>),
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum KnownEnv {
Align,
AlignStar,
Aligned,
Equation,
EquationStar,
Gather,
GatherStar,
Matrix,
Pmatrix,
Bmatrix,
Vmatrix,
Smallmatrix,
Cases,
Array,
Split,
Multline,
MultlineStar,
}
impl KnownEnv {
pub fn from_name(name: &str) -> Option<Self> {
Some(match name {
"align" => Self::Align,
"align*" => Self::AlignStar,
"aligned" => Self::Aligned,
"equation" => Self::Equation,
"equation*" => Self::EquationStar,
"gather" => Self::Gather,
"gather*" => Self::GatherStar,
"matrix" => Self::Matrix,
"pmatrix" => Self::Pmatrix,
"bmatrix" => Self::Bmatrix,
"vmatrix" => Self::Vmatrix,
"smallmatrix" => Self::Smallmatrix,
"cases" => Self::Cases,
"array" => Self::Array,
"split" => Self::Split,
"multline" => Self::Multline,
"multline*" => Self::MultlineStar,
_ => return None,
})
}
pub const fn name(self) -> &'static str {
match self {
Self::Align => "align",
Self::AlignStar => "align*",
Self::Aligned => "aligned",
Self::Equation => "equation",
Self::EquationStar => "equation*",
Self::Gather => "gather",
Self::GatherStar => "gather*",
Self::Matrix => "matrix",
Self::Pmatrix => "pmatrix",
Self::Bmatrix => "bmatrix",
Self::Vmatrix => "vmatrix",
Self::Smallmatrix => "smallmatrix",
Self::Cases => "cases",
Self::Array => "array",
Self::Split => "split",
Self::Multline => "multline",
Self::MultlineStar => "multline*",
}
}
pub const fn is_aligning(self) -> bool {
matches!(
self,
Self::Align
| Self::AlignStar
| Self::Aligned
| Self::Matrix
| Self::Pmatrix
| Self::Bmatrix
| Self::Vmatrix
| Self::Smallmatrix
| Self::Cases
| Self::Array
| Self::Split
)
}
}
impl EnvKind {
pub fn is_aligning(&self) -> bool {
matches!(self, Self::Known(k) if k.is_aligning())
}
pub fn name<'a>(&self, source: &'a str) -> &'a str {
match self {
Self::Known(k) => k.name(),
Self::Custom(range) => source.get(range.clone()).unwrap_or(""),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn known_from_name_round_trips() {
for k in [
KnownEnv::Align,
KnownEnv::AlignStar,
KnownEnv::Pmatrix,
KnownEnv::Cases,
KnownEnv::MultlineStar,
] {
assert_eq!(KnownEnv::from_name(k.name()), Some(k));
}
}
#[test]
fn unknown_name_returns_none() {
assert_eq!(KnownEnv::from_name("tikzcd"), None);
assert_eq!(KnownEnv::from_name("widget"), None);
}
#[test]
fn aligning_split() {
assert!(KnownEnv::Align.is_aligning());
assert!(KnownEnv::Pmatrix.is_aligning());
assert!(KnownEnv::Cases.is_aligning());
assert!(!KnownEnv::Equation.is_aligning());
assert!(!KnownEnv::Gather.is_aligning());
assert!(!KnownEnv::Multline.is_aligning());
}
#[test]
fn custom_is_never_aligning() {
let env = EnvKind::Custom(0..6);
assert!(!env.is_aligning());
}
#[test]
fn custom_name_resolves_from_source() {
let s = "tikzcd";
let env = EnvKind::Custom(0..6);
assert_eq!(env.name(s), "tikzcd");
}
}