use ansi_term::Style; use pest::error::Error; use rayon::prelude::*; use std::collections::BTreeMap; use crate::config::parse_style_string; use crate::segment::Segment; use super::model::*; use super::parser::{parse, Rule}; type VariableMapType = BTreeMap>>; pub struct StringFormatter<'a> { format: Vec>, variables: VariableMapType, } impl<'a> StringFormatter<'a> { /// Creates an instance of StringFormatter from a format string pub fn new(format: &'a str) -> Result> { parse(format) .map(|format| { let variables = _get_variables(&format); (format, variables) }) .map(|(format, variables)| Self { format, variables }) } /// Maps variable name to its value pub fn map(mut self, mapper: impl Fn(&str) -> Option + Sync) -> Self { self.variables.par_iter_mut().for_each(|(key, value)| { *value = mapper(key).map(|value| vec![_new_segment(key.to_string(), value, None)]); }); self } /// Maps variable name to an array of segments pub fn map_variables_to_segments( mut self, mapper: impl Fn(&str) -> Option> + Sync, ) -> Self { self.variables.par_iter_mut().for_each(|(key, value)| { *value = mapper(key); }); self } /// Parse the format string and consume self. pub fn parse(self, default_style: Option