Generalize map config parsing

Maps like the one used by SNIIconSize and SNIPaddingTop are now
generalized, without requiring the awkward std::pair<_,_> buf and hasntFoundProperty helpers
This commit is contained in:
scorpion-26 2023-09-01 23:42:45 +02:00
parent 71278a3529
commit 5c2ac6fa08
2 changed files with 32 additions and 19 deletions

View file

@ -2,8 +2,10 @@
#include <iostream> #include <iostream>
#include <unistd.h> #include <unistd.h>
#include <string> #include <string>
#include <unordered_map>
#include <vector> #include <vector>
#include <filesystem> #include <filesystem>
#include <map>
#include "Log.h" #include "Log.h"
@ -51,6 +53,14 @@ using EnumType = std::underlying_type_t<Enum>;
namespace Utils namespace Utils
{ {
template<typename T>
constexpr bool IsMapLike = false;
template<typename Key, typename Value>
constexpr bool IsMapLike<std::map<Key, Value>> = true;
template<typename Key, typename Value>
constexpr bool IsMapLike<std::unordered_map<Key, Value>> = true;
inline std::string ToStringPrecision(double x, const char* fmt) inline std::string ToStringPrecision(double x, const char* fmt)
{ {
char buf[128]; char buf[128];

View file

@ -72,8 +72,9 @@ void ApplyProperty<bool>(bool& propertyToSet, const std::string_view& value)
} }
} }
template<> // Why does C++ not have partial template specialization?
void ApplyProperty<std::pair<std::string, uint32_t>>(std::pair<std::string, uint32_t>& propertyToSet, const std::string_view& value) template<typename First, typename Second>
void ApplyProperty(std::pair<First, Second>& propertyToSet, const std::string_view& value)
{ {
// TODO: Ignore escaped delimiter (e.g. \, is the same as ,) // TODO: Ignore escaped delimiter (e.g. \, is the same as ,)
const char delim = ','; const char delim = ',';
@ -81,7 +82,6 @@ void ApplyProperty<std::pair<std::string, uint32_t>>(std::pair<std::string, uint
size_t delimPos = value.find(delim); size_t delimPos = value.find(delim);
if (delimPos == std::string::npos) if (delimPos == std::string::npos)
{ {
propertyToSet = {std::string(value), 0};
return; return;
} }
std::string_view before = value.substr(0, delimPos); std::string_view before = value.substr(0, delimPos);
@ -96,7 +96,7 @@ void ApplyProperty<std::pair<std::string, uint32_t>>(std::pair<std::string, uint
ApplyProperty(propertyToSet.second, after); ApplyProperty(propertyToSet.second, after);
} }
template<typename T> template<typename T, std::enable_if_t<!Utils::IsMapLike<T>, bool> = true>
void AddConfigVar(const std::string& propertyName, T& propertyToSet, std::string_view line, bool& setConfig) void AddConfigVar(const std::string& propertyName, T& propertyToSet, std::string_view line, bool& setConfig)
{ {
const char* whitespace = " \t"; const char* whitespace = " \t";
@ -130,11 +130,26 @@ void AddConfigVar(const std::string& propertyName, T& propertyToSet, std::string
value = value.substr(beginValue, endValue - beginValue + 1); value = value.substr(beginValue, endValue - beginValue + 1);
// Set value // Set value
ApplyProperty<T>(propertyToSet, value); ApplyProperty(propertyToSet, value);
LOG("Set value for " << propertyName << ": " << value); LOG("Set value for " << propertyName << ": " << value);
setConfig = true; setConfig = true;
} }
// Specialization for std::[unordered_]map
template<typename MapLike, std::enable_if_t<Utils::IsMapLike<MapLike>, bool> = true>
void AddConfigVar(const std::string& propertyName, MapLike& propertyToSet, std::string_view line, bool& setConfig)
{
bool hasntSetProperty = !setConfig;
std::pair<typename MapLike::key_type, typename MapLike::mapped_type> buf;
AddConfigVar(propertyName, buf, line, setConfig);
if (setConfig && hasntSetProperty)
{
// This was found
propertyToSet[buf.first] = buf.second;
}
}
void Config::Load() void Config::Load()
{ {
const char* xdgConfigHome = getenv("XDG_CONFIG_HOME"); const char* xdgConfigHome = getenv("XDG_CONFIG_HOME");
@ -211,20 +226,8 @@ void Config::Load()
AddConfigVar("Location", config.location, lineView, foundProperty); AddConfigVar("Location", config.location, lineView, foundProperty);
std::pair<std::string, uint32_t> buf; AddConfigVar("SNIIconSize", config.sniIconSizes, lineView, foundProperty);
bool hasntFoundProperty = !foundProperty; AddConfigVar("SNIPaddingTop", config.sniPaddingTop, lineView, foundProperty);
AddConfigVar("SNIIconSize", buf, lineView, foundProperty);
if (foundProperty && hasntFoundProperty)
{
// This was found
config.sniIconSizes[buf.first] = buf.second;
}
hasntFoundProperty = !foundProperty;
AddConfigVar("SNIPaddingTop", buf, lineView, foundProperty);
if (foundProperty && hasntFoundProperty)
{
config.sniPaddingTop[buf.first] = buf.second;
}
if (foundProperty == false) if (foundProperty == false)
{ {