internal: make int errors throw

This commit is contained in:
Vaxry 2024-02-11 16:15:03 +00:00
parent 7c5f672b2f
commit dbe5835573

View file

@ -5,6 +5,7 @@
#include <format> #include <format>
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <expected>
using namespace Hyprlang; using namespace Hyprlang;
extern "C" char** environ; extern "C" char** environ;
@ -177,7 +178,7 @@ static void replaceAll(std::string& str, const std::string& from, const std::str
} }
} }
static int64_t configStringToInt(const std::string& VALUE) { static std::expected<int64_t, std::string> configStringToInt(const std::string& VALUE) {
if (VALUE.starts_with("0x")) { if (VALUE.starts_with("0x")) {
// Values with 0x are hex // Values with 0x are hex
const auto VALUEWITHOUTHEX = VALUE.substr(2); const auto VALUEWITHOUTHEX = VALUE.substr(2);
@ -189,15 +190,21 @@ static int64_t configStringToInt(const std::string& VALUE) {
if (std::count(VALUEWITHOUTFUNC.begin(), VALUEWITHOUTFUNC.end(), ',') == 3) { if (std::count(VALUEWITHOUTFUNC.begin(), VALUEWITHOUTFUNC.end(), ',') == 3) {
// cool // cool
std::string rolling = VALUEWITHOUTFUNC; std::string rolling = VALUEWITHOUTFUNC;
uint8_t r = configStringToInt(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(',')))); auto r = configStringToInt(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(','))));
rolling = rolling.substr(rolling.find(',') + 1); rolling = rolling.substr(rolling.find(',') + 1);
uint8_t g = configStringToInt(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(',')))); auto g = configStringToInt(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(','))));
rolling = rolling.substr(rolling.find(',') + 1); rolling = rolling.substr(rolling.find(',') + 1);
uint8_t b = configStringToInt(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(',')))); auto b = configStringToInt(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(','))));
rolling = rolling.substr(rolling.find(',') + 1); rolling = rolling.substr(rolling.find(',') + 1);
uint8_t a = std::round(std::stof(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(',')))) * 255.f); uint8_t a = 0;
try {
a = std::round(std::stof(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(',')))) * 255.f);
} catch (std::exception& e) { return std::unexpected("failed parsing " + VALUEWITHOUTFUNC); }
return a * 0x1000000L + r * 0x10000L + g * 0x100L + b; if (!r.has_value() || !g.has_value() || !b.has_value())
return std::unexpected("failed parsing " + VALUEWITHOUTFUNC);
return a * 0x1000000L + r.value() * 0x10000L + g.value() * 0x100L + b.value();
} else if (VALUEWITHOUTFUNC.length() == 8) { } else if (VALUEWITHOUTFUNC.length() == 8) {
const auto RGBA = std::stol(VALUEWITHOUTFUNC, nullptr, 16); const auto RGBA = std::stol(VALUEWITHOUTFUNC, nullptr, 16);
@ -205,7 +212,7 @@ static int64_t configStringToInt(const std::string& VALUE) {
return (RGBA >> 8) + 0x1000000 * (RGBA & 0xFF); return (RGBA >> 8) + 0x1000000 * (RGBA & 0xFF);
} }
throw std::invalid_argument("rgba() expects length of 8 characters (4 bytes) or 4 comma separated values"); return std::unexpected("rgba() expects length of 8 characters (4 bytes) or 4 comma separated values");
} else if (VALUE.starts_with("rgb(") && VALUE.ends_with(')')) { } else if (VALUE.starts_with("rgb(") && VALUE.ends_with(')')) {
const auto VALUEWITHOUTFUNC = removeBeginEndSpacesTabs(VALUE.substr(4, VALUE.length() - 5)); const auto VALUEWITHOUTFUNC = removeBeginEndSpacesTabs(VALUE.substr(4, VALUE.length() - 5));
@ -214,20 +221,23 @@ static int64_t configStringToInt(const std::string& VALUE) {
if (std::count(VALUEWITHOUTFUNC.begin(), VALUEWITHOUTFUNC.end(), ',') == 2) { if (std::count(VALUEWITHOUTFUNC.begin(), VALUEWITHOUTFUNC.end(), ',') == 2) {
// cool // cool
std::string rolling = VALUEWITHOUTFUNC; std::string rolling = VALUEWITHOUTFUNC;
uint8_t r = configStringToInt(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(',')))); auto r = configStringToInt(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(','))));
rolling = rolling.substr(rolling.find(',') + 1); rolling = rolling.substr(rolling.find(',') + 1);
uint8_t g = configStringToInt(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(',')))); auto g = configStringToInt(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(','))));
rolling = rolling.substr(rolling.find(',') + 1); rolling = rolling.substr(rolling.find(',') + 1);
uint8_t b = configStringToInt(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(',')))); auto b = configStringToInt(removeBeginEndSpacesTabs(rolling.substr(0, rolling.find(','))));
return 0xFF000000L + r * 0x10000L + g * 0x100L + b; if (!r.has_value() || !g.has_value() || !b.has_value())
return std::unexpected("failed parsing " + VALUEWITHOUTFUNC);
return 0xFF000000L + r.value() * 0x10000L + g.value() * 0x100L + b.value();
} else if (VALUEWITHOUTFUNC.length() == 6) { } else if (VALUEWITHOUTFUNC.length() == 6) {
const auto RGB = std::stol(VALUEWITHOUTFUNC, nullptr, 16); const auto RGB = std::stol(VALUEWITHOUTFUNC, nullptr, 16);
return RGB + 0xFF000000; return RGB + 0xFF000000;
} }
throw std::invalid_argument("rgb() expects length of 6 characters (3 bytes) or 3 comma separated values"); return std::unexpected("rgb() expects length of 6 characters (3 bytes) or 3 comma separated values");
} else if (VALUE.starts_with("true") || VALUE.starts_with("on") || VALUE.starts_with("yes")) { } else if (VALUE.starts_with("true") || VALUE.starts_with("on") || VALUE.starts_with("yes")) {
return 1; return 1;
} else if (VALUE.starts_with("false") || VALUE.starts_with("off") || VALUE.starts_with("no")) { } else if (VALUE.starts_with("false") || VALUE.starts_with("off") || VALUE.starts_with("no")) {
@ -235,9 +245,14 @@ static int64_t configStringToInt(const std::string& VALUE) {
} }
if (VALUE.empty() || !isNumber(VALUE, false)) if (VALUE.empty() || !isNumber(VALUE, false))
return 0; return std::unexpected("cannot parse \"" + VALUE + "\" as an int.");
return std::stoll(VALUE); try {
const auto RES = std::stoll(VALUE);
return RES;
} catch (std::exception& e) { return std::unexpected(std::string{"stoll threw: "} + e.what()); }
return 0;
} }
CParseResult CConfig::configSetValueSafe(const std::string& command, const std::string& value) { CParseResult CConfig::configSetValueSafe(const std::string& command, const std::string& value) {
@ -310,12 +325,15 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std::
switch (VALUEIT->second.m_eType) { switch (VALUEIT->second.m_eType) {
case CConfigValue::eDataType::CONFIGDATATYPE_INT: { case CConfigValue::eDataType::CONFIGDATATYPE_INT: {
try {
VALUEIT->second.setFrom(configStringToInt(value)); const auto INT = configStringToInt(value);
} catch (std::exception& e) { if (!INT.has_value()) {
result.setError(std::format("failed parsing an int: {}", e.what())); result.setError(INT.error());
return result; return result;
} }
VALUEIT->second.setFrom(INT.value());
break; break;
} }
case CConfigValue::eDataType::CONFIGDATATYPE_FLOAT: { case CConfigValue::eDataType::CONFIGDATATYPE_FLOAT: {