use std::fmt;
use aryth::Bound;
use aryth::duobound::matrix::duobound;
use num::Float;
use veho::matrix::{Mappers, trizipper, zipper};
use veho::matrix::Matrix;
use crate::enums::Effect;
use crate::projector::ProjectorFactory;
use crate::types::Preset;
pub fn fluo_rendered<M, R>(
matrix: M,
presets: &(Preset, Preset),
effects: &[Effect],
) -> Matrix<String> where
M: IntoIterator<Item=R>,
R: IntoIterator,
R::Item: fmt::Display
{
let mx: Matrix<String> = matrix.mapper(|el| el.to_string());
let ((mx_x, dye_fac_x),
(mx_y, dye_fac_y)) = make_projector(&mx, presets, effects);
trizipper(mx_x, mx_y, mx, |x, y, tx| {
if let Some(v) = x { return dye_fac_x.render(v, &tx); }
if let Some(v) = y { return dye_fac_y.render(v, &tx); }
return dye_fac_x.render(f32::nan(), &tx);
})
}
pub fn fluo_colorant<M, R>(
matrix: M,
presets: &(Preset, Preset),
effects: &[Effect],
) -> Matrix<impl Fn(&str) -> String> where
M: IntoIterator<Item=R>,
R: IntoIterator,
R::Item: fmt::Display
{
let ((vec_x, dye_fac_x),
(vec_y, dye_fac_y)) = make_projector(matrix, presets, effects);
zipper(vec_x, vec_y, |x, y| {
if let Some(v) = x { return dye_fac_x.make(v); }
if let Some(v) = y { return dye_fac_y.make(v); }
return dye_fac_x.make(f32::nan());
})
}
fn make_projector<M, R>(
vec: M,
presets: &(Preset, Preset),
effects: &[Effect],
) -> ((Matrix<Option<f32>>, ProjectorFactory), (Matrix<Option<f32>>, ProjectorFactory)) where
M: IntoIterator<Item=R>,
R: IntoIterator,
R::Item: fmt::Display
{
let (pre_x, pre_y) = presets;
let (mb_x, mb_y) = duobound(vec);
let (matrix_x, bound_x) = mb_x.move_to_tuple();
let (matrix_y, bound_y) = mb_y.move_to_tuple();
let (bound_x, bound_y) = (
bound_x.unwrap_or_else(Bound::<f32>::default),
bound_y.unwrap_or_else(Bound::<f32>::default),
);
let (fac_x, fac_y) = (
ProjectorFactory::build(&bound_x, &pre_x, effects),
ProjectorFactory::build(&bound_y, &pre_y, effects)
);
return ((matrix_x, fac_x), (matrix_y, fac_y));
}
#[cfg(test)]
mod tests {
use veho::matrix::zipper;
use veho::vector::mapper as mapper_vector;
use crate::presets::{FRESH, OCEAN};
use super::*;
#[test]
fn test_fluo_matrix_rendered() {
let candidates = vec![
vec![
["1", "2", "3"],
["foo", "bar", "zen"],
],
vec![
["1", "2", "3"]
],
vec![
["foo", "bar", "zen"]
]
];
for matrix in &candidates {
let fluoed = fluo_rendered(
matrix,
&(OCEAN, FRESH),
&[Effect::Bold],
);
let tx = mapper_vector(fluoed, |row| format!("[ {} ]", row.join(", "))).join(", ");
println!("[ {} ]", tx);
}
}
#[test]
fn test_fluo_matrix_colorant() {
let candidates = vec![
vec![
["1", "2", "3"],
["foo", "bar", "zen"],
],
vec![
["1", "2", "3"]
],
vec![
["foo", "bar", "zen"]
]
];
for matrix in &candidates {
let fluoed = fluo_colorant(
matrix,
&(OCEAN, FRESH),
&[Effect::Bold],
);
let results = zipper(matrix, fluoed, |x, f| {
f(x)
});
let tx = mapper_vector(results, |row| format!("[ {} ]", row.join(", "))).join(", ");
println!("[ {} ]", tx);
}
}
}