| // Copyright (c) 2021 Pantor. All rights reserved. |
| |
| #ifndef INCLUDE_INJA_FUNCTION_STORAGE_HPP_ |
| #define INCLUDE_INJA_FUNCTION_STORAGE_HPP_ |
| |
| #include <vector> |
| |
| #include "string_view.hpp" |
| |
| namespace inja { |
| |
| using json = nlohmann::json; |
| |
| using Arguments = std::vector<const json *>; |
| using CallbackFunction = std::function<json(Arguments &args)>; |
| using VoidCallbackFunction = std::function<void(Arguments &args)>; |
| |
| /*! |
| * \brief Class for builtin functions and user-defined callbacks. |
| */ |
| class FunctionStorage { |
| public: |
| enum class Operation { |
| Not, |
| And, |
| Or, |
| In, |
| Equal, |
| NotEqual, |
| Greater, |
| GreaterEqual, |
| Less, |
| LessEqual, |
| Add, |
| Subtract, |
| Multiplication, |
| Division, |
| Power, |
| Modulo, |
| AtId, |
| At, |
| Default, |
| DivisibleBy, |
| Even, |
| Exists, |
| ExistsInObject, |
| First, |
| Float, |
| Int, |
| IsArray, |
| IsBoolean, |
| IsFloat, |
| IsInteger, |
| IsNumber, |
| IsObject, |
| IsString, |
| Last, |
| Length, |
| Lower, |
| Max, |
| Min, |
| Odd, |
| Range, |
| Round, |
| Sort, |
| Upper, |
| Super, |
| Callback, |
| ParenLeft, |
| ParenRight, |
| None, |
| }; |
| |
| struct FunctionData { |
| explicit FunctionData(const Operation &op, const CallbackFunction &cb = CallbackFunction{}) : operation(op), callback(cb) {} |
| const Operation operation; |
| const CallbackFunction callback; |
| }; |
| |
| private: |
| const int VARIADIC {-1}; |
| |
| std::map<std::pair<std::string, int>, FunctionData> function_storage = { |
| {std::make_pair("at", 2), FunctionData { Operation::At }}, |
| {std::make_pair("default", 2), FunctionData { Operation::Default }}, |
| {std::make_pair("divisibleBy", 2), FunctionData { Operation::DivisibleBy }}, |
| {std::make_pair("even", 1), FunctionData { Operation::Even }}, |
| {std::make_pair("exists", 1), FunctionData { Operation::Exists }}, |
| {std::make_pair("existsIn", 2), FunctionData { Operation::ExistsInObject }}, |
| {std::make_pair("first", 1), FunctionData { Operation::First }}, |
| {std::make_pair("float", 1), FunctionData { Operation::Float }}, |
| {std::make_pair("int", 1), FunctionData { Operation::Int }}, |
| {std::make_pair("isArray", 1), FunctionData { Operation::IsArray }}, |
| {std::make_pair("isBoolean", 1), FunctionData { Operation::IsBoolean }}, |
| {std::make_pair("isFloat", 1), FunctionData { Operation::IsFloat }}, |
| {std::make_pair("isInteger", 1), FunctionData { Operation::IsInteger }}, |
| {std::make_pair("isNumber", 1), FunctionData { Operation::IsNumber }}, |
| {std::make_pair("isObject", 1), FunctionData { Operation::IsObject }}, |
| {std::make_pair("isString", 1), FunctionData { Operation::IsString }}, |
| {std::make_pair("last", 1), FunctionData { Operation::Last }}, |
| {std::make_pair("length", 1), FunctionData { Operation::Length }}, |
| {std::make_pair("lower", 1), FunctionData { Operation::Lower }}, |
| {std::make_pair("max", 1), FunctionData { Operation::Max }}, |
| {std::make_pair("min", 1), FunctionData { Operation::Min }}, |
| {std::make_pair("odd", 1), FunctionData { Operation::Odd }}, |
| {std::make_pair("range", 1), FunctionData { Operation::Range }}, |
| {std::make_pair("round", 2), FunctionData { Operation::Round }}, |
| {std::make_pair("sort", 1), FunctionData { Operation::Sort }}, |
| {std::make_pair("upper", 1), FunctionData { Operation::Upper }}, |
| {std::make_pair("super", 0), FunctionData { Operation::Super }}, |
| {std::make_pair("super", 1), FunctionData { Operation::Super }}, |
| }; |
| |
| public: |
| void add_builtin(nonstd::string_view name, int num_args, Operation op) { |
| function_storage.emplace(std::make_pair(static_cast<std::string>(name), num_args), FunctionData { op }); |
| } |
| |
| void add_callback(nonstd::string_view name, int num_args, const CallbackFunction &callback) { |
| function_storage.emplace(std::make_pair(static_cast<std::string>(name), num_args), FunctionData { Operation::Callback, callback }); |
| } |
| |
| FunctionData find_function(nonstd::string_view name, int num_args) const { |
| auto it = function_storage.find(std::make_pair(static_cast<std::string>(name), num_args)); |
| if (it != function_storage.end()) { |
| return it->second; |
| |
| // Find variadic function |
| } else if (num_args > 0) { |
| it = function_storage.find(std::make_pair(static_cast<std::string>(name), VARIADIC)); |
| if (it != function_storage.end()) { |
| return it->second; |
| } |
| } |
| |
| return FunctionData { Operation::None }; |
| } |
| }; |
| |
| } // namespace inja |
| |
| #endif // INCLUDE_INJA_FUNCTION_STORAGE_HPP_ |