1use handles::{hex, rgb, hsl, cmyk, hsv};
2use std::fmt;
3use std::error::Error as StdError;
4
5#[derive(Debug)]
7pub struct Color<'a> {
8 pub mode: ColorMode<'a>,
9 pub upper: bool,
10 pub android: bool,
11 pub alpha: bool
12}
13impl<'a> Color<'a> {
14 pub fn init(mode: &'a str, upper: bool, android: bool, alpha: bool) -> Self {
16 Color {
17 mode: ColorMode::new(mode),
18 upper,
19 android,
20 alpha
21 }
22 }
23 pub fn new(mode: &'a str) -> Self {
25 Color {
26 mode: ColorMode::new(mode),
27 upper: false,
28 android: false,
29 alpha: false
30 }
31 }
32 pub fn copy(&self, mode: &'a str) -> Self {
34 Color {
35 mode: ColorMode::new(mode),
36 upper: self.upper,
37 android: self.android,
38 alpha: self.alpha
39 }
40 }
41
42 pub fn to_upper(&mut self, to_upper: bool) -> &Self {
44 self.upper = to_upper;
45 self
46 }
47 pub fn to_android(&mut self, to_android: bool) -> &Self {
48 self.android = to_android;
49 self
50 }
51 pub fn to_alpha(&mut self, to_alpha: bool) -> &Self {
52 self.alpha = to_alpha;
53 self
54 }
55 pub fn to_str(&self) -> &str {
56 match self.mode {
57 ColorMode::HEX(color) => color,
58 ColorMode::RGB(color) => color,
59 ColorMode::RGBA(color) => color,
60 ColorMode::HSL(color) => color,
61 ColorMode::HSLA(color) => color,
62 ColorMode::HSV(color) => color,
63 ColorMode::CMYK(color) => color,
64 }
65 }
66
67 pub fn to_rgb(&self) -> Result<String, Error> {
68 match self.mode {
69 ColorMode::HEX(_) => hex::hex2rgb(self),
70 ColorMode::RGB(_) => rgb::rgb2rgb(self),
71 ColorMode::RGBA(_) => rgb::rgb2rgb(self),
72 ColorMode::HSL(_) => hsl::hsl2rgb(self),
73 ColorMode::HSLA(_) => hsl::hsl2rgb(self),
74 ColorMode::CMYK(_) => cmyk::cmyk2rgb(self),
75 ColorMode::HSV(_) => hsv::hsv2rgb(self),
76 }
77 }
78
79 pub fn to_hex(&self) -> Result<String, Error> {
80 match self.mode {
81 ColorMode::HEX(_) => hex::hex2hex(self),
82 ColorMode::RGB(_) => rgb::rgb2hex(self),
83 ColorMode::RGBA(_) => rgb::rgb2hex(self),
84 ColorMode::HSL(_) => hsl::hsl2hex(self),
85 ColorMode::HSLA(_) => hsl::hsl2hex(self),
86 ColorMode::CMYK(_) => cmyk::cmyk2hex(self),
87 ColorMode::HSV(_) => hsv::hsv2hex(self),
88 }
89 }
90
91 pub fn to_hsl(&self) -> Result<String, Error> {
92 match self.mode {
93 ColorMode::HEX(_) => hex::hex2hsl(self),
94 ColorMode::RGB(_) => rgb::rgb2hsl(self),
95 ColorMode::RGBA(_) => rgb::rgb2hsl(self),
96 ColorMode::HSL(_) => hsl::hsl2hsl(self),
97 ColorMode::HSLA(_) => hsl::hsl2hsl(self),
98 ColorMode::CMYK(_) => cmyk::cmyk2hsl(self),
99 ColorMode::HSV(_) => hsv::hsv2hsl(self),
100 }
101 }
102
103 pub fn to_cmyk(&self) -> Result<String, Error> {
104 match self.mode {
105 ColorMode::HEX(_) => hex::hex2cmyk(self),
106 ColorMode::RGB(_) => rgb::rgb2cmyk(self),
107 ColorMode::RGBA(_) => rgb::rgb2cmyk(self),
108 ColorMode::HSL(_) => hsl::hsl2cmyk(self),
109 ColorMode::HSLA(_) => hsl::hsl2cmyk(self),
110 ColorMode::CMYK(_) => cmyk::cmyk2cmyk(self),
111 ColorMode::HSV(_) => hsv::hsv2cmyk(self),
112 }
113 }
114
115 pub fn to_hsv(&self) -> Result<String, Error> {
116 match self.mode {
117 ColorMode::HEX(_) => hex::hex2hsl(self),
118 ColorMode::RGB(_) => rgb::rgb2hsv(self),
119 ColorMode::RGBA(_) => rgb::rgb2hsv(self),
120 ColorMode::HSL(_) => hsl::hsl2hsv(self),
121 ColorMode::HSLA(_) => hsl::hsl2hsv(self),
122 ColorMode::CMYK(_) => cmyk::cmyk2hsv(self),
123 ColorMode::HSV(_) => hsv::hsv2hsv(self),
124 }
125 }
126}
127
128#[derive(Debug)]
129pub enum ColorMode<'a> {
131 RGBA(&'a str),
132 RGB(&'a str),
133 HSLA(&'a str),
134 HSL(&'a str),
135 CMYK(&'a str),
136 HSV(&'a str),
137 HEX(&'a str)
138}
139
140impl<'a> ColorMode<'a> {
141 pub fn new(color: &'a str) -> ColorMode {
142 let upper_color = color.to_ascii_uppercase();
143
144 if upper_color.contains("RGBA") {
145 ColorMode::RGBA(color)
146 } else if upper_color.contains("RGB") {
147 ColorMode::RGB(color)
148 } else if upper_color.contains("HSLA") {
149 ColorMode::HSLA(color)
150 } else if upper_color.contains("HSL") {
151 ColorMode::HSL(color)
152 } else if upper_color.contains("CMYK") {
153 ColorMode::CMYK(color)
154 } else if upper_color.contains("HSV") {
155 ColorMode::HSV(color)
156 } else {
157 ColorMode::HEX(color)
158 }
159 }
160}
161
162impl<'a> PartialEq for ColorMode<'a> {
163 fn eq(&self, other: &ColorMode) -> bool {
164 match (self, other) {
165 (ColorMode::RGBA(i), ColorMode::RGBA(j)) => i == j,
166 (ColorMode::RGB(i), ColorMode::RGB(j)) => i == j,
167 (ColorMode::HSLA(i), ColorMode::HSLA(j)) => i == j,
168 (ColorMode::HSL(i), ColorMode::HSL(j)) => i == j,
169 (ColorMode::CMYK(i), ColorMode::CMYK(j)) => i == j,
170 (ColorMode::HSV(i), ColorMode::HSV(j)) => i == j,
171 (ColorMode::HEX(i), ColorMode::HEX(j)) => i == j,
172 _ => false
173 }
174 }
175}
176
177#[derive(Debug)]
178pub enum Error {
179 Format,
180 NotMatch,
181 RgbAlphaFormat
182}
183
184impl fmt::Display for Error {
185 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
186 match *self {
187 Error::Format => write!(f, "Format Error"),
188 Error::NotMatch => write!(f, "NotMatch Color"),
189 Error::RgbAlphaFormat => write!(f, "Rgba Alpha Format Error")
190 }
191 }
192}
193
194impl StdError for Error {
195 fn description(&self) -> &str {
196 match *self {
197 Error::Format => "[color-convert] Color value is illegal.",
198 Error::NotMatch => "[color-convert] No match color value.",
199 Error::RgbAlphaFormat => "alpha value is not a number, unable to convert to f32"
200 }
201 }
202}