[text_sensor] Use std::array in MapFilter

This commit is contained in:
J. Nick Koston
2026-03-27 13:34:36 -10:00
parent a075f63b59
commit 27c609531d
3 changed files with 25 additions and 13 deletions
+1 -1
View File
@@ -136,7 +136,7 @@ async def map_filter_to_code(config, filter_id):
)
for conf in config
]
return cg.new_Pvariable(filter_id, mappings)
return cg.new_Pvariable(filter_id, cg.TemplateArguments(len(mappings)), mappings)
validate_device_class = cv.one_of(*DEVICE_CLASSES, lower=True, space="_")
+6 -8
View File
@@ -93,17 +93,15 @@ bool SubstituteFilter::new_value(std::string &value) {
return true;
}
// Map
MapFilter::MapFilter(const std::initializer_list<Substitution> &mappings) : mappings_(mappings) {}
bool MapFilter::new_value(std::string &value) {
for (const auto &mapping : this->mappings_) {
if (value == mapping.from) {
value.assign(mapping.to);
// Map — non-template helper
bool map_filter_apply(const Substitution *mappings, size_t count, std::string &value) {
for (size_t i = 0; i < count; i++) {
if (value == mappings[i].from) {
value.assign(mappings[i].to);
return true;
}
}
return true; // Pass through if no match
return true;
}
} // namespace esphome::text_sensor
+18 -4
View File
@@ -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"
@@ -131,6 +133,9 @@ class SubstituteFilter : public Filter {
FixedVector<Substitution> substitutions_;
};
/// Non-template helper (implementation in filter.cpp)
bool map_filter_apply(const Substitution *mappings, size_t count, std::string &value);
/** A filter that maps values from one set to another
*
* Uses linear search instead of std::map for typical small datasets (2-20 mappings).
@@ -154,14 +159,23 @@ class SubstituteFilter : public Filter {
* - Faster for typical ESPHome usage (2-10 mappings common, 20+ rare)
*
* Break-even point: ~35-40 mappings, but ESPHome configs rarely exceed 20
*
* N is set by code generation to match the exact number of mappings configured in YAML.
*/
class MapFilter : public Filter {
template<size_t N> class MapFilter : public Filter {
public:
explicit MapFilter(const std::initializer_list<Substitution> &mappings);
bool new_value(std::string &value) override;
explicit MapFilter(const std::initializer_list<Substitution> &mappings) {
size_t i = 0;
for (const auto &m : mappings) {
if (i >= N)
break;
this->mappings_[i++] = m;
}
}
bool new_value(std::string &value) override { return map_filter_apply(this->mappings_.data(), N, value); }
protected:
FixedVector<Substitution> mappings_;
std::array<Substitution, N> mappings_{};
};
} // namespace esphome::text_sensor