summaryrefslogtreecommitdiff
path: root/src/config/theme/style.rs
blob: 6e8d16159f5b56c96b61335bf7c15aa480d15fb6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use std::str::FromStr;

use mlua::{FromLua, IntoLua};
use ratatui::style::{Color, Styled, Stylize};

#[derive(Clone, Copy, Debug)]
pub struct Style {
    pub fg: Option<Color>,
    pub bg: Option<Color>,
    pub italic: bool,
    pub bold: bool,
    pub underlined: bool
}

impl Style {
    pub const fn new() -> Self {
        Self {
            fg: None,
            bg: None,
            italic: false,
            bold: false,
            underlined: false,
        }
    }

    pub const fn fg(mut self, color: Color) -> Self {
        self.fg = Some(color);
        self
    }

    pub const fn bg(mut self, color: Color) -> Self {
        self.bg = Some(color);
        self
    }

    pub fn apply<S, I>(&self, s: S) -> <S as Styled>::Item
    where
        S: Styled<Item = I>,
        I: Styled,
    {
        let mut style = ratatui::style::Style::default();

        if let Some(fg) = self.fg {
            style = style.fg(fg)
        }

        if let Some(bg) = self.bg {
            style = style.bg(bg)
        }

        if self.italic {
            style = style.italic()
        }

        if self.bold {
            style = style.bold()
        }

        if self.underlined {
            style = style.underlined()
        }

        s.set_style(style)
    }
}

impl<'lua> FromLua<'lua> for Style {
    fn from_lua(
        value: mlua::prelude::LuaValue<'lua>,
        _lua: &'lua mlua::prelude::Lua,
    ) -> mlua::prelude::LuaResult<Self> {
        if value.is_table() {
            let table = value.as_table().unwrap();
            let mut style = Style::new();

            if let Ok(fg) = table.get::<_, String>("fg").or_else(|_| table.get(1)) {
                match Color::from_str(&fg) {
                    Ok(fg) => style.fg = Some(fg),
                    Err(_) => return Err(mlua::Error::runtime("could not parse fg"))
                }
            }

            if let Ok(bg) = table.get::<_, String>("bg").or_else(|_| table.get(2)) {
                match Color::from_str(&bg) {
                    Ok(bg) => style.bg = Some(bg),
                    Err(_) => return Err(mlua::Error::runtime("could not parse bg"))
                }
            }

            if let Ok(italic) = table.get::<_, bool>("italic") {
                style.italic = italic
            }

            if let Ok(bold) = table.get::<_, bool>("bold") {
                style.bold = bold
            }

            if let Ok(underlined) = table.get::<_, bool>("underlined") {
                style.underlined = underlined
            }

            return Ok(style)
        }

        return Err(mlua::Error::runtime("could not parse style"));
    }
}

impl<'lua> IntoLua<'lua> for Style {
    fn into_lua(
        self,
        lua: &'lua mlua::prelude::Lua,
    ) -> mlua::prelude::LuaResult<mlua::prelude::LuaValue<'lua>> {
        let table = lua.create_table()?;
        table.set("fg", self.fg.map(|s| s.to_string()).into_lua(lua)?)?;
        table.set("bg", self.bg.map(|s| s.to_string()).into_lua(lua)?)?;
        Ok(table.into_lua(lua)?)
    }
}