@@ -829,6 +829,82 @@ Mod_concat::load(Config &cfg, YAML::Node, TextView, TextView, YAML::Node key_val
829829
830830// ---
831831
832+ // / Convert the feature to boolean.
833+ class Mod_as_bool : public Modifier
834+ {
835+ using self_type = Mod_as_bool;
836+ using super_type = Modifier;
837+
838+ public:
839+ inline static const std::string KEY = " as-bool" ; // /< Identifier name.
840+
841+ /* * Modify the feature.
842+ *
843+ * @param ctx Run time context.
844+ * @param feature Feature to modify [in,out]
845+ * @return Errors, if any.
846+ */
847+ Rv<Feature> operator ()(Context &ctx, Feature &feature) override ;
848+
849+ /* * Check if @a ftype is a valid type to be modified.
850+ *
851+ * @param ftype Type of feature to modify.
852+ * @return @c true if this modifier can modity that feature type, @c false if not.
853+ */
854+ bool is_valid_for (ActiveType const &ex_type) const override ;
855+
856+ // / Resulting type of feature after modifying.
857+ ActiveType result_type (ActiveType const &) const override ;
858+
859+ /* * Create an instance from YAML config.
860+ *
861+ * @param cfg Configuration state object.
862+ * @param mod_node Node with modifier.
863+ * @param key_node Node in @a mod_node that identifies the modifier.
864+ * @return A constructed instance or errors.
865+ */
866+ static Rv<Handle> load (Config &cfg, YAML::Node node, TextView key, TextView arg, YAML::Node key_value);
867+
868+ protected:
869+ inline static const auto VALUE_TYPES = MaskFor({STRING, INTEGER, FLOAT, BOOLEAN, TUPLE, IP_ADDR, NIL});
870+ Expr _value; // /< Default value.
871+
872+ explicit Mod_as_bool (Expr &&expr) : _value(std::move(expr)) {}
873+ };
874+
875+ bool
876+ Mod_as_bool::is_valid_for (ActiveType const &ex_type) const
877+ {
878+ return ex_type.can_satisfy (VALUE_TYPES);
879+ }
880+
881+ ActiveType
882+ Mod_as_bool::result_type (ActiveType const &) const
883+ {
884+ return {BOOLEAN};
885+ }
886+
887+ Rv<Feature>
888+ Mod_as_bool::operator ()(Context &, Feature &feature)
889+ {
890+ return { feature.as_bool () };
891+ }
892+
893+ Rv<Modifier::Handle>
894+ Mod_as_bool::load (Config &cfg, YAML::Node, TextView, TextView, YAML::Node key_value)
895+ {
896+ auto &&[expr, errata]{cfg.parse_expr (key_value)};
897+ if (!errata.is_ok ()) {
898+ errata.note (R"( While parsing "{}" modifier at {}.)" , KEY, key_value.Mark ());
899+ return std::move (errata);
900+ }
901+ if (!(expr.is_null () || expr.result_type ().can_satisfy (VALUE_TYPES))) {
902+ return Errata (S_ERROR, " Value of {} modifier is not of type {}." , KEY, VALUE_TYPES);
903+ }
904+ return Handle (new self_type{std::move (expr)});
905+ }
906+
907+ // --- //
832908// / Convert the feature to an Integer.
833909class Mod_as_integer : public Modifier
834910{
@@ -1253,6 +1329,7 @@ namespace
12531329 Modifier::define (Mod_else::KEY, &Mod_else::load);
12541330 Modifier::define (Mod_join::KEY, &Mod_join::load);
12551331 Modifier::define (Mod_concat::KEY, &Mod_concat::load);
1332+ Modifier::define (Mod_as_bool::KEY, &Mod_as_bool::load);
12561333 Modifier::define (Mod_as_integer::KEY, &Mod_as_integer::load);
12571334 Modifier::define (Mod_As_Duration::KEY, &Mod_As_Duration::load);
12581335 Modifier::define (Mod_filter::KEY, &Mod_filter::load);
0 commit comments