mirror of
https://github.com/rad4day/Waybar.git
synced 2025-07-14 07:02:30 +02:00
refactor: separate regex rule matching and caching in separate class
This commit is contained in:
69
src/util/regex_collection.cpp
Normal file
69
src/util/regex_collection.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
#include "util/regex_collection.hpp"
|
||||
|
||||
#include <json/value.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
namespace waybar::util {
|
||||
|
||||
int default_priority_function(std::string& key) { return 0; }
|
||||
|
||||
RegexCollection::RegexCollection(const Json::Value& map, std::string default_repr,
|
||||
std::function<int(std::string&)> priority_function)
|
||||
: default_repr(default_repr) {
|
||||
if (!map.isObject()) {
|
||||
spdlog::warn("Mapping is not an object");
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto it = map.begin(); it != map.end(); ++it) {
|
||||
if (it.key().isString() && it->isString()) {
|
||||
std::string key = it.key().asString();
|
||||
int priority = priority_function(key);
|
||||
try {
|
||||
const std::regex rule{key, std::regex_constants::icase};
|
||||
rules.emplace_back(rule, it->asString(), priority);
|
||||
} catch (const std::regex_error& e) {
|
||||
spdlog::error("Invalid rule '{}': {}", key, e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(rules.begin(), rules.end(), [](Rule& a, Rule& b) { return a.priority > b.priority; });
|
||||
}
|
||||
|
||||
std::string& RegexCollection::find_match(std::string& value, bool& matched_any) {
|
||||
for (auto& rule : rules) {
|
||||
if (std::regex_search(value, rule.rule)) {
|
||||
matched_any = true;
|
||||
return rule.repr;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string& RegexCollection::get(std::string& value, bool& matched_any) {
|
||||
if (regex_cache.contains(value)) {
|
||||
return regex_cache[value];
|
||||
}
|
||||
|
||||
// std::string repr =
|
||||
// waybar::util::find_match(value, window_rewrite_rules_, matched_any);
|
||||
|
||||
std::string repr = find_match(value, matched_any);
|
||||
|
||||
if (!matched_any) {
|
||||
repr = default_repr;
|
||||
}
|
||||
|
||||
regex_cache.emplace(value, repr);
|
||||
|
||||
return regex_cache[value]; // Necessary in order to return a reference to the heap
|
||||
}
|
||||
|
||||
std::string& RegexCollection::get(std::string& value) {
|
||||
bool matched_any = false;
|
||||
return get(value, matched_any);
|
||||
}
|
||||
|
||||
} // namespace waybar::util
|
@ -1,6 +1,5 @@
|
||||
#include "util/rewrite_string.hpp"
|
||||
|
||||
#include <fmt/core.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include <regex>
|
||||
@ -30,31 +29,4 @@ std::string rewriteString(const std::string& value, const Json::Value& rules) {
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string rewriteStringOnce(const std::string& value, const Json::Value& rules,
|
||||
bool& matched_any) {
|
||||
if (!rules.isObject()) {
|
||||
return value;
|
||||
}
|
||||
|
||||
matched_any = false;
|
||||
|
||||
std::string res = value;
|
||||
|
||||
for (auto it = rules.begin(); it != rules.end(); ++it) {
|
||||
if (it.key().isString() && it->isString()) {
|
||||
try {
|
||||
const std::regex rule{it.key().asString(), std::regex_constants::icase};
|
||||
if (std::regex_match(value, rule)) {
|
||||
matched_any = true;
|
||||
return std::regex_replace(res, rule, it->asString());
|
||||
}
|
||||
} catch (const std::regex_error& e) {
|
||||
spdlog::error("Invalid rule {}: {}", it.key().asString(), e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
} // namespace waybar::util
|
||||
|
Reference in New Issue
Block a user