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
// Take a look at the license at the top of the repository in the LICENSE file.

use std::fmt;

use glib::translate::*;

use crate::Color;

impl Color {
    /// Fill in the fields of a color from a string specification.
    ///
    /// The string can either one of a large set of standard names.
    /// (Taken from the CSS Color [specification](https://www.w3.org/TR/css-color-4/#named-colors),
    /// or it can be a value in the form `#rgb`, `#rrggbb`,
    /// `#rrrgggbbb` or `#rrrrggggbbbb`, where `r`, `g` and `b`
    /// are hex digits of the red, green, and blue components
    /// of the color, respectively. (White in the four forms is
    /// `#fff`, `#ffffff`, `#fffffffff` and `#ffffffffffff`.)
    /// ## `spec`
    /// a string specifying the new color
    ///
    /// # Returns
    ///
    /// [`true`] if parsing of the specifier succeeded,
    ///   otherwise [`false`]
    #[doc(alias = "pango_color_parse")]
    pub fn parse(spec: &str) -> Result<Self, glib::BoolError> {
        unsafe {
            let mut color = Self::uninitialized();
            let is_success =
                ffi::pango_color_parse(color.to_glib_none_mut().0, spec.to_glib_none().0);
            if from_glib(is_success) {
                Ok(color)
            } else {
                Err(glib::bool_error!("Failed to parse the color"))
            }
        }
    }

    /// Fill in the fields of a color from a string specification.
    ///
    /// The string can either one of a large set of standard names.
    /// (Taken from the CSS Color [specification](https://www.w3.org/TR/css-color-4/#named-colors),
    /// or it can be a hexadecimal value in the form `#rgb`,
    /// `#rrggbb`, `#rrrgggbbb` or `#rrrrggggbbbb` where `r`, `g`
    /// and `b` are hex digits of the red, green, and blue components
    /// of the color, respectively. (White in the four forms is
    /// `#fff`, `#ffffff`, `#fffffffff` and `#ffffffffffff`.)
    ///
    /// Additionally, parse strings of the form `#rgba`, `#rrggbbaa`,
    /// `#rrrrggggbbbbaaaa`, if @alpha is not [`None`], and set @alpha
    /// to the value specified by the hex digits for `a`. If no alpha
    /// component is found in @spec, @alpha is set to 0xffff (for a
    /// solid color).
    /// ## `spec`
    /// a string specifying the new color
    ///
    /// # Returns
    ///
    /// [`true`] if parsing of the specifier succeeded,
    ///   otherwise [`false`]
    ///
    /// ## `alpha`
    /// return location for alpha
    #[cfg(feature = "v1_46")]
    #[cfg_attr(docsrs, doc(cfg(feature = "v1_46")))]
    #[doc(alias = "pango_color_parse_with_alpha")]
    pub fn parse_with_alpha(spec: &str) -> Result<(Self, u16), glib::BoolError> {
        unsafe {
            let mut color = Self::uninitialized();
            let mut alpha = std::mem::MaybeUninit::uninit();
            let is_success = ffi::pango_color_parse_with_alpha(
                color.to_glib_none_mut().0,
                alpha.as_mut_ptr(),
                spec.to_glib_none().0,
            );
            if from_glib(is_success) {
                Ok((color, alpha.assume_init()))
            } else {
                Err(glib::bool_error!("Failed to parse the color with alpha"))
            }
        }
    }

    pub fn red(&self) -> u16 {
        unsafe { *self.to_glib_none().0 }.red
    }

    pub fn green(&self) -> u16 {
        unsafe { *self.to_glib_none().0 }.green
    }

    pub fn blue(&self) -> u16 {
        unsafe { *self.to_glib_none().0 }.blue
    }
}

impl fmt::Debug for Color {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("Color")
            .field("red", &self.red())
            .field("green", &self.green())
            .field("blue", &self.blue())
            .finish()
    }
}

impl std::str::FromStr for Color {
    type Err = glib::BoolError;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Color::parse(s)
    }
}