blob: b4bd092de103f69cf849cbedcb230df7be4e0353 [file] [log] [blame]
// 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,
Join,
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 }},
{std::make_pair("join", 2), FunctionData { Operation::Join }},
};
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_