syncat_stylesheet/style/
value.rs

1use crate::ast::Color;
2#[cfg(feature = "ansi_term")]
3use ansi_term::Color as ANSIColor;
4use std::convert::TryFrom;
5use std::error::Error;
6use std::fmt::{self, Display, Formatter};
7
8#[derive(Clone, Debug)]
9pub enum Value {
10    String(String),
11    Boolean(bool),
12    Number(u32),
13    Color(Color),
14}
15
16#[derive(Debug)]
17pub struct FromValueError {
18    value: Value,
19    target: &'static str,
20}
21
22impl FromValueError {
23    pub fn new(value: Value, target: &'static str) -> Self {
24        Self { value, target }
25    }
26}
27
28impl Error for FromValueError {}
29
30impl Display for FromValueError {
31    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
32        write!(
33            f,
34            "failed conversion from stylesheet value {:?} to type {}",
35            self.value, self.target
36        )
37    }
38}
39
40impl TryFrom<Value> for String {
41    type Error = FromValueError;
42    fn try_from(value: Value) -> Result<Self, Self::Error> {
43        match value {
44            Value::String(value) => Ok(value),
45            _ => Err(FromValueError::new(value, "String")),
46        }
47    }
48}
49
50impl TryFrom<Value> for u32 {
51    type Error = FromValueError;
52    fn try_from(value: Value) -> Result<Self, Self::Error> {
53        match value {
54            Value::Number(value) => Ok(value),
55            _ => Err(FromValueError::new(value, "u32")),
56        }
57    }
58}
59
60impl TryFrom<Value> for bool {
61    type Error = FromValueError;
62    fn try_from(value: Value) -> Result<Self, Self::Error> {
63        match value {
64            Value::Boolean(value) => Ok(value),
65            _ => Err(FromValueError::new(value, "bool")),
66        }
67    }
68}
69
70impl TryFrom<Value> for Color {
71    type Error = FromValueError;
72    fn try_from(value: Value) -> Result<Self, Self::Error> {
73        match value {
74            Value::Color(value) => Ok(value),
75            _ => Err(FromValueError::new(value, "Color")),
76        }
77    }
78}
79
80#[cfg(feature = "ansi_term")]
81impl TryFrom<Value> for ANSIColor {
82    type Error = FromValueError;
83    fn try_from(value: Value) -> Result<Self, Self::Error> {
84        match value {
85            Value::Color(Color::Black) => Ok(ANSIColor::Black),
86            Value::Color(Color::Red) => Ok(ANSIColor::Red),
87            Value::Color(Color::Green) => Ok(ANSIColor::Green),
88            Value::Color(Color::Yellow) => Ok(ANSIColor::Yellow),
89            Value::Color(Color::Blue) => Ok(ANSIColor::Blue),
90            Value::Color(Color::Purple) => Ok(ANSIColor::Purple),
91            Value::Color(Color::Cyan) => Ok(ANSIColor::Cyan),
92            Value::Color(Color::White) => Ok(ANSIColor::White),
93            Value::Color(Color::BrBlack) => Ok(ANSIColor::Fixed(8)),
94            Value::Color(Color::BrRed) => Ok(ANSIColor::Fixed(9)),
95            Value::Color(Color::BrGreen) => Ok(ANSIColor::Fixed(10)),
96            Value::Color(Color::BrYellow) => Ok(ANSIColor::Fixed(11)),
97            Value::Color(Color::BrBlue) => Ok(ANSIColor::Fixed(12)),
98            Value::Color(Color::BrPurple) => Ok(ANSIColor::Fixed(13)),
99            Value::Color(Color::BrCyan) => Ok(ANSIColor::Fixed(14)),
100            Value::Color(Color::BrWhite) => Ok(ANSIColor::Fixed(15)),
101            Value::Color(Color::Hex(value)) => Ok(ANSIColor::RGB(
102                ((value >> 16) & 0xFF) as u8,
103                ((value >> 8) & 0xFF) as u8,
104                (value & 0xFF) as u8,
105            )),
106            _ => Err(FromValueError::new(value, "ansi_term::Colour")),
107        }
108    }
109}