Skip to content

Commit 5bf4f52

Browse files
authored
feat: implement From trait for termion to Style related structs (#692)
* feat(termion): implement from termion color * feat(termion): implement from termion style * feat(termion): implement from termion `Bg` and `Fg`
1 parent f4c8de0 commit 5bf4f52

File tree

1 file changed

+223
-1
lines changed

1 file changed

+223
-1
lines changed

src/backend/termion.rs

+223-1
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ use std::{
99
io::{self, Write},
1010
};
1111

12+
use termion::{color as tcolor, style as tstyle};
13+
1214
use crate::{
1315
backend::{Backend, ClearType, WindowSize},
1416
buffer::Cell,
1517
prelude::Rect,
16-
style::{Color, Modifier},
18+
style::{Color, Modifier, Style},
1719
};
1820

1921
/// A [`Backend`] implementation that uses [Termion] to render to the terminal.
@@ -275,6 +277,82 @@ impl fmt::Display for Bg {
275277
}
276278
}
277279

280+
macro_rules! from_termion_for_color {
281+
($termion_color:ident, $color: ident) => {
282+
impl From<tcolor::$termion_color> for Color {
283+
fn from(_: tcolor::$termion_color) -> Self {
284+
Color::$color
285+
}
286+
}
287+
288+
impl From<tcolor::Bg<tcolor::$termion_color>> for Style {
289+
fn from(_: tcolor::Bg<tcolor::$termion_color>) -> Self {
290+
Style::default().bg(Color::$color)
291+
}
292+
}
293+
294+
impl From<tcolor::Fg<tcolor::$termion_color>> for Style {
295+
fn from(_: tcolor::Fg<tcolor::$termion_color>) -> Self {
296+
Style::default().fg(Color::$color)
297+
}
298+
}
299+
};
300+
}
301+
302+
from_termion_for_color!(Reset, Reset);
303+
from_termion_for_color!(Black, Black);
304+
from_termion_for_color!(Red, Red);
305+
from_termion_for_color!(Green, Green);
306+
from_termion_for_color!(Yellow, Yellow);
307+
from_termion_for_color!(Blue, Blue);
308+
from_termion_for_color!(Magenta, Magenta);
309+
from_termion_for_color!(Cyan, Cyan);
310+
from_termion_for_color!(White, Gray);
311+
from_termion_for_color!(LightBlack, DarkGray);
312+
from_termion_for_color!(LightRed, LightRed);
313+
from_termion_for_color!(LightGreen, LightGreen);
314+
from_termion_for_color!(LightBlue, LightBlue);
315+
from_termion_for_color!(LightYellow, LightYellow);
316+
from_termion_for_color!(LightMagenta, LightMagenta);
317+
from_termion_for_color!(LightCyan, LightCyan);
318+
from_termion_for_color!(LightWhite, White);
319+
320+
impl From<tcolor::AnsiValue> for Color {
321+
fn from(value: tcolor::AnsiValue) -> Self {
322+
Color::Indexed(value.0)
323+
}
324+
}
325+
326+
impl From<tcolor::Bg<tcolor::AnsiValue>> for Style {
327+
fn from(value: tcolor::Bg<tcolor::AnsiValue>) -> Self {
328+
Style::default().bg(Color::Indexed(value.0 .0))
329+
}
330+
}
331+
332+
impl From<tcolor::Fg<tcolor::AnsiValue>> for Style {
333+
fn from(value: tcolor::Fg<tcolor::AnsiValue>) -> Self {
334+
Style::default().fg(Color::Indexed(value.0 .0))
335+
}
336+
}
337+
338+
impl From<tcolor::Rgb> for Color {
339+
fn from(value: tcolor::Rgb) -> Self {
340+
Color::Rgb(value.0, value.1, value.2)
341+
}
342+
}
343+
344+
impl From<tcolor::Bg<tcolor::Rgb>> for Style {
345+
fn from(value: tcolor::Bg<tcolor::Rgb>) -> Self {
346+
Style::default().bg(Color::Rgb(value.0 .0, value.0 .1, value.0 .2))
347+
}
348+
}
349+
350+
impl From<tcolor::Fg<tcolor::Rgb>> for Style {
351+
fn from(value: tcolor::Fg<tcolor::Rgb>) -> Self {
352+
Style::default().fg(Color::Rgb(value.0 .0, value.0 .1, value.0 .2))
353+
}
354+
}
355+
278356
impl fmt::Display for ModifierDiff {
279357
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
280358
let remove = self.from - self.to;
@@ -339,3 +417,147 @@ impl fmt::Display for ModifierDiff {
339417
Ok(())
340418
}
341419
}
420+
421+
macro_rules! from_termion_for_modifier {
422+
($termion_modifier:ident, $modifier: ident) => {
423+
impl From<tstyle::$termion_modifier> for Modifier {
424+
fn from(_: tstyle::$termion_modifier) -> Self {
425+
Modifier::$modifier
426+
}
427+
}
428+
};
429+
}
430+
431+
from_termion_for_modifier!(Invert, REVERSED);
432+
from_termion_for_modifier!(Bold, BOLD);
433+
from_termion_for_modifier!(Italic, ITALIC);
434+
from_termion_for_modifier!(Underline, UNDERLINED);
435+
from_termion_for_modifier!(Faint, DIM);
436+
from_termion_for_modifier!(CrossedOut, CROSSED_OUT);
437+
from_termion_for_modifier!(Blink, SLOW_BLINK);
438+
439+
impl From<termion::style::Reset> for Modifier {
440+
fn from(_: termion::style::Reset) -> Self {
441+
Modifier::empty()
442+
}
443+
}
444+
445+
#[cfg(test)]
446+
mod tests {
447+
use super::*;
448+
use crate::style::Stylize;
449+
450+
#[test]
451+
fn from_termion_color() {
452+
assert_eq!(Color::from(tcolor::Reset), Color::Reset);
453+
assert_eq!(Color::from(tcolor::Black), Color::Black);
454+
assert_eq!(Color::from(tcolor::Red), Color::Red);
455+
assert_eq!(Color::from(tcolor::Green), Color::Green);
456+
assert_eq!(Color::from(tcolor::Yellow), Color::Yellow);
457+
assert_eq!(Color::from(tcolor::Blue), Color::Blue);
458+
assert_eq!(Color::from(tcolor::Magenta), Color::Magenta);
459+
assert_eq!(Color::from(tcolor::Cyan), Color::Cyan);
460+
assert_eq!(Color::from(tcolor::White), Color::Gray);
461+
assert_eq!(Color::from(tcolor::LightBlack), Color::DarkGray);
462+
assert_eq!(Color::from(tcolor::LightRed), Color::LightRed);
463+
assert_eq!(Color::from(tcolor::LightGreen), Color::LightGreen);
464+
assert_eq!(Color::from(tcolor::LightBlue), Color::LightBlue);
465+
assert_eq!(Color::from(tcolor::LightYellow), Color::LightYellow);
466+
assert_eq!(Color::from(tcolor::LightMagenta), Color::LightMagenta);
467+
assert_eq!(Color::from(tcolor::LightCyan), Color::LightCyan);
468+
assert_eq!(Color::from(tcolor::LightWhite), Color::White);
469+
assert_eq!(Color::from(tcolor::AnsiValue(31)), Color::Indexed(31));
470+
assert_eq!(Color::from(tcolor::Rgb(1, 2, 3)), Color::Rgb(1, 2, 3));
471+
}
472+
473+
#[test]
474+
fn from_termion_bg() {
475+
use tc::Bg;
476+
use tcolor as tc;
477+
478+
assert_eq!(Style::from(Bg(tc::Reset)), Style::new().bg(Color::Reset));
479+
assert_eq!(Style::from(Bg(tc::Black)), Style::new().on_black());
480+
assert_eq!(Style::from(Bg(tc::Red)), Style::new().on_red());
481+
assert_eq!(Style::from(Bg(tc::Green)), Style::new().on_green());
482+
assert_eq!(Style::from(Bg(tc::Yellow)), Style::new().on_yellow());
483+
assert_eq!(Style::from(Bg(tc::Blue)), Style::new().on_blue());
484+
assert_eq!(Style::from(Bg(tc::Magenta)), Style::new().on_magenta());
485+
assert_eq!(Style::from(Bg(tc::Cyan)), Style::new().on_cyan());
486+
assert_eq!(Style::from(Bg(tc::White)), Style::new().on_gray());
487+
assert_eq!(Style::from(Bg(tc::LightBlack)), Style::new().on_dark_gray());
488+
assert_eq!(Style::from(Bg(tc::LightRed)), Style::new().on_light_red());
489+
assert_eq!(
490+
Style::from(Bg(tc::LightGreen)),
491+
Style::new().on_light_green()
492+
);
493+
assert_eq!(Style::from(Bg(tc::LightBlue)), Style::new().on_light_blue());
494+
assert_eq!(
495+
Style::from(Bg(tc::LightYellow)),
496+
Style::new().on_light_yellow()
497+
);
498+
assert_eq!(
499+
Style::from(Bg(tc::LightMagenta)),
500+
Style::new().on_light_magenta()
501+
);
502+
assert_eq!(Style::from(Bg(tc::LightCyan)), Style::new().on_light_cyan());
503+
assert_eq!(Style::from(Bg(tc::LightWhite)), Style::new().on_white());
504+
assert_eq!(
505+
Style::from(Bg(tc::AnsiValue(31))),
506+
Style::new().bg(Color::Indexed(31))
507+
);
508+
assert_eq!(
509+
Style::from(Bg(tc::Rgb(1, 2, 3))),
510+
Style::new().bg(Color::Rgb(1, 2, 3))
511+
);
512+
}
513+
514+
#[test]
515+
fn from_termion_fg() {
516+
use tc::Fg;
517+
use tcolor as tc;
518+
519+
assert_eq!(Style::from(Fg(tc::Reset)), Style::new().fg(Color::Reset));
520+
assert_eq!(Style::from(Fg(tc::Black)), Style::new().black());
521+
assert_eq!(Style::from(Fg(tc::Red)), Style::new().red());
522+
assert_eq!(Style::from(Fg(tc::Green)), Style::new().green());
523+
assert_eq!(Style::from(Fg(tc::Yellow)), Style::new().yellow());
524+
assert_eq!(Style::from(Fg(tc::Blue)), Style::default().blue());
525+
assert_eq!(Style::from(Fg(tc::Magenta)), Style::default().magenta());
526+
assert_eq!(Style::from(Fg(tc::Cyan)), Style::default().cyan());
527+
assert_eq!(Style::from(Fg(tc::White)), Style::default().gray());
528+
assert_eq!(Style::from(Fg(tc::LightBlack)), Style::new().dark_gray());
529+
assert_eq!(Style::from(Fg(tc::LightRed)), Style::new().light_red());
530+
assert_eq!(Style::from(Fg(tc::LightGreen)), Style::new().light_green());
531+
assert_eq!(Style::from(Fg(tc::LightBlue)), Style::new().light_blue());
532+
assert_eq!(
533+
Style::from(Fg(tc::LightYellow)),
534+
Style::new().light_yellow()
535+
);
536+
assert_eq!(
537+
Style::from(Fg(tc::LightMagenta)),
538+
Style::new().light_magenta()
539+
);
540+
assert_eq!(Style::from(Fg(tc::LightCyan)), Style::new().light_cyan());
541+
assert_eq!(Style::from(Fg(tc::LightWhite)), Style::new().white());
542+
assert_eq!(
543+
Style::from(Fg(tc::AnsiValue(31))),
544+
Style::default().fg(Color::Indexed(31))
545+
);
546+
assert_eq!(
547+
Style::from(Fg(tc::Rgb(1, 2, 3))),
548+
Style::default().fg(Color::Rgb(1, 2, 3))
549+
);
550+
}
551+
552+
#[test]
553+
fn from_termion_style() {
554+
assert_eq!(Modifier::from(tstyle::Invert), Modifier::REVERSED);
555+
assert_eq!(Modifier::from(tstyle::Bold), Modifier::BOLD);
556+
assert_eq!(Modifier::from(tstyle::Italic), Modifier::ITALIC);
557+
assert_eq!(Modifier::from(tstyle::Underline), Modifier::UNDERLINED);
558+
assert_eq!(Modifier::from(tstyle::Faint), Modifier::DIM);
559+
assert_eq!(Modifier::from(tstyle::CrossedOut), Modifier::CROSSED_OUT);
560+
assert_eq!(Modifier::from(tstyle::Blink), Modifier::SLOW_BLINK);
561+
assert_eq!(Modifier::from(tstyle::Reset), Modifier::empty());
562+
}
563+
}

0 commit comments

Comments
 (0)