use crate::{lin_sys::{
err::OutOfBoundsError,
numbering::{Numbering, NumberingTy},
}, latex_modes::{MathLatexMode, CategoryEnumVariantExt, MathLatexModeKind, CategorizedLatexModeKindExt}};
use core::{fmt::Write, marker::PhantomData};
use either::Either;
use nalgebra::Dim;
pub trait Unknowns {
fn write_latex<IM,OM,W>(&self, dest: &mut W) -> Result<(), core::fmt::Error>
where
IM: CategorizedLatexModeKindExt,
OM: MathLatexMode + CategoryEnumVariantExt<MathLatexModeKind>,
W: Write;
fn validate_idx(&self, zbi: usize) -> Result<(), OutOfBoundsError>;
unsafe fn write_latex_for_ith_unchecked<M,W>(
&self,
dest: &mut W,
zbi: usize,
) -> Result<(), core::fmt::Error>
where
M: MathLatexMode + CategoryEnumVariantExt<MathLatexModeKind>,
W: Write;
fn write_latex_for_ith<M,W>(
&self,
dest: &mut W,
zbi: usize,
) -> Result<(), Either<core::fmt::Error, OutOfBoundsError>>
where
M: MathLatexMode + CategoryEnumVariantExt<MathLatexModeKind>,
W: Write
{
self.validate_idx(zbi).map_err(Either::Right)?;
unsafe {
self.write_latex_for_ith_unchecked::<M,W>(dest, zbi)
.map_err(Either::Left)
}
}
}
pub struct SingleLetterBoldfaceVecOfUnknowns<L, const N: NumberingTy> {
pub c: char,
pub len: L,
phantom: PhantomData<()>,
}
impl<L, const N: NumberingTy> SingleLetterBoldfaceVecOfUnknowns<L, N> {
#[cfg_attr(not(feature = "adt_const_params"), allow(non_upper_case_globals))]
pub fn new(c: char, len: L) -> Self {
use Numbering::*;
debug_assert!(matches!(N, ZeroBased | OneBased));
Self {
c,
len,
phantom: PhantomData::<()>,
}
}
}
impl<L, const N: NumberingTy> Unknowns for SingleLetterBoldfaceVecOfUnknowns<L,N>
where
L: Copy + Dim,
{
fn write_latex<IM,OM,W>(&self, w: &mut W) -> Result<(), core::fmt::Error>
where
IM: CategorizedLatexModeKindExt,
OM: MathLatexMode + CategoryEnumVariantExt<MathLatexModeKind>,
W: Write,
{
w.write_fmt(format_args!("\\textbf{{{}}}", self.c))
}
fn validate_idx(&self, zbi: usize) -> Result<(), OutOfBoundsError> {
if zbi >= self.len.value() {
Err(OutOfBoundsError)
} else {
Ok(())
}
}
#[cfg_attr(not(feature = "adt_const_params"), allow(non_upper_case_globals))]
unsafe fn write_latex_for_ith_unchecked<M,W>(
&self,
w: &mut W,
zbi: usize,
) -> Result<(), core::fmt::Error>
where
M: MathLatexMode + CategoryEnumVariantExt<MathLatexModeKind>,
W: Write
{
use Numbering::*;
w.write_fmt(format_args!(
"{}_{{{}}}",
self.c,
match N {
ZeroBased => zbi,
OneBased => zbi + 1,
#[cfg_attr(feature = "adt_const_params", allow(unreachable_patterns))]
_ => panic!("unsupported numbering"),
}
))
}
}