text_style/
cursive.rs

1// SPDX-FileCopyrightText: 2020-2021 Robin Krahl <robin.krahl@ireas.org>
2// SPDX-License-Identifier: Apache-2.0 or MIT
3
4//! Conversion methods for [`cursive`][]’s text style types.
5//!
6//! *Requires the `cursive` feature.*
7//!
8//! This module implements these conversions:
9//! - [`AnsiColor`][] to [`cursive::theme::BaseColor`][]
10//! - [`Color`][] to [`cursive::theme::Color`][]
11//! - [`Effect`][] to [`cursive::theme::Effect`][]
12//! - [`Style`][] to [`cursive::theme::Style`][]
13//! - [`StyledStr`][] and [`StyledString`][] to [`cursive::utils::markup::StyledString`][]
14//!
15//! # Example
16//!
17//! Rendering a string:
18//!
19//! ```
20//! let text = text_style::StyledStr::plain("test").bold();
21//! let mut s = cursive::dummy();
22//! s.add_layer(cursive::views::TextView::new(text));
23//! s.add_global_callback('q', |s| s.quit());
24//! s.run();
25//! ```
26//!
27//! [`cursive`]: https://docs.rs/cursive
28//! [`cursive::theme::BaseColor`]: https://docs.rs/cursive/latest/cursive/theme/enum.BaseColor.html
29//! [`cursive::theme::Color`]: https://docs.rs/cursive/latest/cursive/theme/enum.Color.html
30//! [`cursive::theme::Effect`]: https://docs.rs/cursive/latest/cursive/theme/enum.Effect.html
31//! [`cursive::theme::Style`]: https://docs.rs/cursive/latest/cursive/theme/struct.Style.html
32//! [`cursive::utils::markup::StyledString`]: https://docs.rs/cursive/latest/cursive/utils/markup/type.StyledString.html
33//! [`AnsiColor`]: ../enum.AnsiColor.html
34//! [`Color`]: ../enum.Color.html
35//! [`Effect`]: ../enum.Effect.html
36//! [`Style`]: ../struct.Style.html
37//! [`StyledStr`]: ../struct.StyledStr.html
38//! [`StyledString`]: ../struct.StyledString.html
39
40use cursive::{theme, utils::markup};
41
42use crate::{AnsiColor, AnsiMode, Color, Effect, Style, StyledStr, StyledString};
43
44impl From<Color> for theme::Color {
45    fn from(color: Color) -> theme::Color {
46        match color {
47            Color::Ansi { color, mode } => match mode {
48                AnsiMode::Dark => theme::Color::Dark(color.into()),
49                AnsiMode::Light => theme::Color::Light(color.into()),
50            },
51            Color::Rgb { r, g, b } => theme::Color::Rgb(r, g, b),
52        }
53    }
54}
55
56impl From<AnsiColor> for theme::BaseColor {
57    fn from(color: AnsiColor) -> theme::BaseColor {
58        match color {
59            AnsiColor::Black => theme::BaseColor::Black,
60            AnsiColor::Red => theme::BaseColor::Red,
61            AnsiColor::Green => theme::BaseColor::Green,
62            AnsiColor::Yellow => theme::BaseColor::Yellow,
63            AnsiColor::Blue => theme::BaseColor::Blue,
64            AnsiColor::Magenta => theme::BaseColor::Magenta,
65            AnsiColor::Cyan => theme::BaseColor::Cyan,
66            AnsiColor::White => theme::BaseColor::White,
67        }
68    }
69}
70
71impl From<Effect> for theme::Effect {
72    fn from(effect: Effect) -> theme::Effect {
73        match effect {
74            Effect::Bold => theme::Effect::Bold,
75            Effect::Italic => theme::Effect::Italic,
76            Effect::Underline => theme::Effect::Underline,
77            Effect::Strikethrough => theme::Effect::Strikethrough,
78        }
79    }
80}
81
82impl From<Style> for theme::Style {
83    fn from(style: Style) -> theme::Style {
84        theme::Style {
85            effects: style.effects.into_iter().map(theme::Effect::from).collect(),
86            color: get_color_style(style.fg, style.bg),
87        }
88    }
89}
90
91fn get_color_style(fg: Option<Color>, bg: Option<Color>) -> theme::ColorStyle {
92    let fg = fg
93        .map(theme::Color::from)
94        .map(theme::ColorType::from)
95        .unwrap_or_default();
96    let bg = bg
97        .map(theme::Color::from)
98        .map(theme::ColorType::from)
99        .unwrap_or_default();
100    theme::ColorStyle::new(fg, bg)
101}
102
103impl<'a, 'b> From<&'b StyledStr<'a>> for markup::StyledString {
104    fn from(s: &'b StyledStr<'a>) -> markup::StyledString {
105        if let Some(style) = s.style {
106            markup::StyledString::styled(s.s.to_owned(), style)
107        } else {
108            markup::StyledString::plain(s.s.to_owned())
109        }
110    }
111}
112
113impl<'a> From<StyledStr<'a>> for markup::StyledString {
114    fn from(s: StyledStr<'a>) -> markup::StyledString {
115        if let Some(style) = s.style {
116            markup::StyledString::styled(s.s.to_owned(), style)
117        } else {
118            markup::StyledString::plain(s.s.to_owned())
119        }
120    }
121}
122
123impl From<StyledString> for markup::StyledString {
124    fn from(s: StyledString) -> markup::StyledString {
125        if let Some(style) = s.style {
126            markup::StyledString::styled(s.s, style)
127        } else {
128            markup::StyledString::plain(s.s)
129        }
130    }
131}