mirror of
https://github.com/esphome/esphome.git
synced 2026-07-10 17:05:36 +00:00
[text_sensor] Use std::array in SubstituteFilter
This commit is contained in:
@@ -123,7 +123,9 @@ async def substitute_filter_to_code(config, filter_id):
|
||||
)
|
||||
for conf in config
|
||||
]
|
||||
return cg.new_Pvariable(filter_id, substitutions)
|
||||
return cg.new_Pvariable(
|
||||
filter_id, cg.TemplateArguments(len(substitutions)), substitutions
|
||||
)
|
||||
|
||||
|
||||
@FILTER_REGISTRY.register("map", MapFilter, cv.ensure_list(validate_mapping))
|
||||
|
||||
@@ -73,20 +73,14 @@ bool PrependFilter::new_value(std::string &value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Substitute
|
||||
SubstituteFilter::SubstituteFilter(const std::initializer_list<Substitution> &substitutions)
|
||||
: substitutions_(substitutions) {}
|
||||
|
||||
bool SubstituteFilter::new_value(std::string &value) {
|
||||
for (const auto &sub : this->substitutions_) {
|
||||
// Compute lengths once per substitution (strlen is fast, called infrequently)
|
||||
const size_t from_len = strlen(sub.from);
|
||||
const size_t to_len = strlen(sub.to);
|
||||
// Substitute — non-template helper
|
||||
bool substitute_filter_apply(const Substitution *substitutions, size_t count, std::string &value) {
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
const size_t from_len = strlen(substitutions[i].from);
|
||||
const size_t to_len = strlen(substitutions[i].to);
|
||||
std::size_t pos = 0;
|
||||
while ((pos = value.find(sub.from, pos, from_len)) != std::string::npos) {
|
||||
value.replace(pos, from_len, sub.to, to_len);
|
||||
// Advance past the replacement to avoid infinite loop when
|
||||
// the replacement contains the search pattern (e.g., f -> foo)
|
||||
while ((pos = value.find(substitutions[i].from, pos, from_len)) != std::string::npos) {
|
||||
value.replace(pos, from_len, substitutions[i].to, to_len);
|
||||
pos += to_len;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include "esphome/core/defines.h"
|
||||
#ifdef USE_TEXT_SENSOR_FILTER
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
@@ -121,14 +123,25 @@ struct Substitution {
|
||||
const char *to;
|
||||
};
|
||||
|
||||
/// A simple filter that replaces a substring with another substring
|
||||
class SubstituteFilter : public Filter {
|
||||
/// Non-template helper (implementation in filter.cpp)
|
||||
bool substitute_filter_apply(const Substitution *substitutions, size_t count, std::string &value);
|
||||
|
||||
/// A simple filter that replaces a substring with another substring.
|
||||
/// N is set by code generation to match the exact number of substitutions configured in YAML.
|
||||
template<size_t N> class SubstituteFilter : public Filter {
|
||||
public:
|
||||
explicit SubstituteFilter(const std::initializer_list<Substitution> &substitutions);
|
||||
bool new_value(std::string &value) override;
|
||||
explicit SubstituteFilter(const std::initializer_list<Substitution> &substitutions) {
|
||||
size_t i = 0;
|
||||
for (const auto &s : substitutions) {
|
||||
if (i >= N)
|
||||
break;
|
||||
this->substitutions_[i++] = s;
|
||||
}
|
||||
}
|
||||
bool new_value(std::string &value) override { return substitute_filter_apply(this->substitutions_.data(), N, value); }
|
||||
|
||||
protected:
|
||||
FixedVector<Substitution> substitutions_;
|
||||
std::array<Substitution, N> substitutions_{};
|
||||
};
|
||||
|
||||
/** A filter that maps values from one set to another
|
||||
|
||||
Reference in New Issue
Block a user