Skip to content

Commit 4262ac8

Browse files
ivovandongenkkaefer
authored andcommitted
return empty optional when color could not be parsed
1 parent 4feb2b9 commit 4262ac8

File tree

4 files changed

+32
-24
lines changed

4 files changed

+32
-24
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CXXFLAGS = -std=c++11 -Wall -Wextra -Wpedantic -Wno-unused-parameter
1+
CXXFLAGS = -std=c++14 -Wall -Wextra -Wpedantic -Wno-unused-parameter
22

33
build: test
44

csscolorparser.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ std::vector<std::string> split(const std::string& s, char delim) {
179179
return elems;
180180
}
181181

182-
Color parse(const std::string& css_str) {
182+
optional<Color> parse(const std::string& css_str) {
183183
std::string str = css_str;
184184

185185
// Remove all whitespace, not compliant, but should just be more accepting.
@@ -191,7 +191,7 @@ Color parse(const std::string& css_str) {
191191

192192
for (size_t i = 0; i < namedColorCount; i++) {
193193
if (str == namedColors[i].name) {
194-
return namedColors[i].color;
194+
return { namedColors[i].color };
195195
}
196196
}
197197

@@ -202,24 +202,24 @@ Color parse(const std::string& css_str) {
202202
if (!(iv >= 0 && iv <= 0xfff)) {
203203
return {};
204204
} else {
205-
return {
205+
return {{
206206
static_cast<uint8_t>(((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8)),
207207
static_cast<uint8_t>((iv & 0xf0) | ((iv & 0xf0) >> 4)),
208208
static_cast<uint8_t>((iv & 0xf) | ((iv & 0xf) << 4)),
209209
1
210-
};
210+
}};
211211
}
212212
} else if (str.length() == 7) {
213213
int64_t iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.
214214
if (!(iv >= 0 && iv <= 0xffffff)) {
215215
return {}; // Covers NaN.
216216
} else {
217-
return {
217+
return {{
218218
static_cast<uint8_t>((iv & 0xff0000) >> 16),
219219
static_cast<uint8_t>((iv & 0xff00) >> 8),
220220
static_cast<uint8_t>(iv & 0xff),
221221
1
222-
};
222+
}};
223223
}
224224
}
225225

@@ -245,12 +245,12 @@ Color parse(const std::string& css_str) {
245245
}
246246
}
247247

248-
return {
248+
return {{
249249
parse_css_int(params[0]),
250250
parse_css_int(params[1]),
251251
parse_css_int(params[2]),
252252
alpha
253-
};
253+
}};
254254

255255
} else if (fname == "hsla" || fname == "hsl") {
256256
if (fname == "hsla") {
@@ -276,12 +276,12 @@ Color parse(const std::string& css_str) {
276276
float m2 = l <= 0.5f ? l * (s + 1.0f) : l + s - l * s;
277277
float m1 = l * 2.0f - m2;
278278

279-
return {
279+
return {{
280280
clamp_css_byte(css_hue_to_rgb(m1, m2, h + 1.0f / 3.0f) * 255.0f),
281281
clamp_css_byte(css_hue_to_rgb(m1, m2, h) * 255.0f),
282282
clamp_css_byte(css_hue_to_rgb(m1, m2, h - 1.0f / 3.0f) * 255.0f),
283283
alpha
284-
};
284+
}};
285285
}
286286
}
287287

csscolorparser.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,13 @@
2727

2828
#include <string>
2929
#include <cmath>
30+
#include <experimental/optional>
3031

3132
namespace CSSColorParser {
3233

34+
template <class T>
35+
using optional = std::experimental::optional<T>;
36+
3337
struct Color {
3438
inline Color() {
3539
}
@@ -41,14 +45,14 @@ struct Color {
4145
};
4246

4347
inline bool operator==(const Color& lhs, const Color& rhs) {
44-
return lhs.r == rhs.r && lhs.g == rhs.g && lhs.b == rhs.b && ::fabs(lhs.a - lhs.b) < 0.0001f;
48+
return lhs.r == rhs.r && lhs.g == rhs.g && lhs.b == rhs.b && ::fabs(lhs.a - rhs.a) < 0.0001f;
4549
}
4650

4751
inline bool operator!=(const Color& lhs, const Color& rhs) {
4852
return !(lhs == rhs);
4953
}
5054

51-
Color parse(const std::string& css_str);
55+
optional<Color> parse(const std::string& css_str);
5256

5357
} // namespace CSSColorParser
5458

test.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,34 @@
44

55
using namespace CSSColorParser;
66

7-
std::ostream& operator<<(std::ostream& os, const Color& color) {
8-
return os << "rgba(" << int(color.r) << ", " << int(color.g) << ", " << int(color.b) << ", "
9-
<< color.a << ")";
7+
std::ostream& operator<<(std::ostream& os, const optional<Color>& color) {
8+
if (color) {
9+
return os << "rgba(" << int(color->r) << ", " << int(color->g) << ", " << int(color->b)
10+
<< ", " << color->a << ")";
11+
} else {
12+
return os << "<no color>";
13+
}
1014
}
1115

1216
static bool errored = false;
1317

14-
void ASSERT_EQUAL(const Color& expected, const std::string& input) {
18+
void ASSERT_EQUAL(const optional<Color>& expected, const std::string& input) {
1519
const auto actual = parse(input);
1620
if (expected != actual) {
1721
errored = true;
1822
std::cerr << "\033[1mERROR!: expected " << expected << " != parsed " << actual
1923
<< " when parsing \"" << input << "\"\033[0m" << std::endl;
2024
} else {
21-
std::cerr << "Passed: " << actual << std::endl;
25+
std::cerr << "Passed: " << actual << " expected when parsing \"" << input << "\"" << std::endl;
2226
}
2327
}
2428

25-
void ASSERT_EQUAL(const Color& expected, const Color& actual) {
29+
void ASSERT_EQUAL(const optional<Color>& expected, const optional<Color>& actual) {
2630
if (expected != actual) {
2731
errored = true;
2832
std::cerr << "\033[1mERROR!: expected " << expected << " != actual " << actual << "\"\033[0m" << std::endl;
2933
} else {
30-
std::cerr << "Passed: " << actual << std::endl;
34+
std::cerr << "Passed: " << actual << " expected" << std::endl;
3135
}
3236
}
3337

@@ -37,15 +41,15 @@ int main() {
3741
ASSERT_EQUAL(Color{ 255, 255, 255, 1 }, "#fff");
3842
ASSERT_EQUAL(Color{ 255, 0, 17, 1 }, "#ff0011");
3943
ASSERT_EQUAL(Color{ 106, 90, 205, 1 }, "slateblue");
40-
ASSERT_EQUAL(Color{ 0, 0, 0, 1 }, "blah");
41-
ASSERT_EQUAL(Color{ 0, 0, 0, 1 }, "ffffff");
44+
ASSERT_EQUAL({}, "blah");
45+
ASSERT_EQUAL({}, "ffffff");
4246
ASSERT_EQUAL(Color{ 226, 233, 233, 0.5 }, "hsla(900, 15%, 90%, 0.5)");
43-
ASSERT_EQUAL(Color{ 0, 0, 0, 1 }, "hsla(900, 15%, 90%)");
47+
ASSERT_EQUAL({}, "hsla(900, 15%, 90%)");
4448
ASSERT_EQUAL(Color{ 226, 233, 233, 1 }, "hsl(900, 15%, 90%)");
4549
ASSERT_EQUAL(Color{ 226, 233, 233, 1 }, "hsl(900, 0.15, 90%)"); // NOTE: not spec compliamt.
4650

4751
// Out of range:
48-
ASSERT_EQUAL(Color{ 0, 0, 0, 1 }, "xxx");
52+
ASSERT_EQUAL({}, "xxx");
4953
ASSERT_EQUAL(Color{ 255, 128, 12, 1 }, " rgba (255, 128, 12, 2)");
5054
ASSERT_EQUAL(Color{ 255, 128, 12, 1 }, " rgba (400, 128, 12, 2)");
5155
ASSERT_EQUAL(Color{ 255, 128, 12, 1 }, Color{ 255, 128, 12, 3 });

0 commit comments

Comments
 (0)