1 use { 2 crate::{ 3 compound_style::CompoundStyle, 4 errors::Result, 5 }, 6 crossterm::{ 7 QueueableCommand, 8 style::{Color, PrintStyledContent, StyledContent}, 9 }, 10 std::fmt::{self, Display}, 11 }; 12 13 /// A modifiable character which can be easily written or repeated. Can 14 /// be used for bullets, horizontal rules or quote marks. 15 #[derive(Clone, Debug)] 16 pub struct StyledChar { 17 compound_style: CompoundStyle, 18 nude_char: char, 19 styled_char: StyledContent<char>, // redundant, kept for performance 20 } 21 22 impl StyledChar { new(compound_style: CompoundStyle, nude_char: char) -> StyledChar23 pub fn new(compound_style: CompoundStyle, nude_char: char) -> StyledChar { 24 Self { 25 nude_char, 26 styled_char: compound_style.apply_to(nude_char), 27 compound_style, 28 } 29 } nude(nude_char: char) -> StyledChar30 pub fn nude(nude_char: char) -> StyledChar { 31 Self::new(CompoundStyle::default(), nude_char) 32 } from_fg_char(fg: Color, nude_char: char) -> StyledChar33 pub fn from_fg_char(fg: Color, nude_char: char) -> StyledChar { 34 Self::new(CompoundStyle::with_fg(fg), nude_char) 35 } 36 /// Change the char, keeping colors and attributes set_char(&mut self, nude_char: char)37 pub fn set_char(&mut self, nude_char: char) { 38 self.nude_char = nude_char; 39 self.styled_char = self.compound_style.apply_to(self.nude_char); 40 } get_char(&self) -> char41 pub fn get_char(&self) -> char { 42 self.nude_char 43 } 44 /// Change the fg color, keeping the char, bg color and attributes set_fg(&mut self, color: Color)45 pub fn set_fg(&mut self, color: Color) { 46 self.compound_style.set_fg(color); 47 self.styled_char = self.compound_style.apply_to(self.nude_char); 48 } get_fg(&self) -> Option<Color>49 pub fn get_fg(&self) -> Option<Color> { 50 self.compound_style.get_fg() 51 } 52 /// Change the bg color, keeping the char, fg color and attributes set_bg(&mut self, color: Color)53 pub fn set_bg(&mut self, color: Color) { 54 self.compound_style.set_bg(color); 55 self.styled_char = self.compound_style.apply_to(self.nude_char); 56 } get_bg(&self) -> Option<Color>57 pub fn get_bg(&self) -> Option<Color> { 58 self.compound_style.get_bg() 59 } 60 /// Change the style (colors, attributes) of the styled char set_compound_style(&mut self, compound_style: CompoundStyle)61 pub fn set_compound_style(&mut self, compound_style: CompoundStyle) { 62 self.compound_style = compound_style; 63 self.styled_char = self.compound_style.apply_to(self.nude_char); 64 } 65 /// Return a struct implementing `Display`, made of a (optimized) repetition 66 /// of the character with its style. repeated(&self, count: usize) -> StyledContent<String>67 pub fn repeated(&self, count: usize) -> StyledContent<String> { 68 let mut s = String::new(); 69 for _ in 0..count { 70 s.push(self.nude_char); 71 } 72 self.compound_style.apply_to(s) 73 } queue_repeat<W>(&self, w: &mut W, count: usize) -> Result<()> where W: std::io::Write,74 pub fn queue_repeat<W>(&self, w: &mut W, count: usize) -> Result<()> 75 where 76 W: std::io::Write, 77 { 78 let mut s = String::new(); 79 for _ in 0..count { 80 s.push(self.nude_char); 81 } 82 self.compound_style.queue(w, s) 83 } queue<W>(&self, w: &mut W) -> Result<()> where W: std::io::Write,84 pub fn queue<W>(&self, w: &mut W) -> Result<()> 85 where 86 W: std::io::Write, 87 { 88 w.queue(PrintStyledContent(self.styled_char.clone()))?; 89 Ok(()) 90 } 91 } 92 93 impl Display for StyledChar { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result94 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 95 self.styled_char.fmt(f) 96 } 97 } 98