mirror of
https://github.com/oatpp/oatpp.git
synced 2024-11-21 03:14:51 +08:00
data::share::StringTemplate. Format string template using ValueProvider.
This commit is contained in:
parent
9003a680c0
commit
a6aaa1eb48
@ -28,6 +28,38 @@
|
||||
|
||||
namespace oatpp { namespace data { namespace share {
|
||||
|
||||
StringTemplate::VectorValueProvider::VectorValueProvider(const std::vector<oatpp::String> *params)
|
||||
: m_params(params)
|
||||
{}
|
||||
|
||||
oatpp::String StringTemplate::VectorValueProvider::getValue(const Variable& variable, v_uint32 index) {
|
||||
(void) variable;
|
||||
return m_params->at(index);
|
||||
}
|
||||
|
||||
StringTemplate::MapValueProvider::MapValueProvider(const std::unordered_map<oatpp::String, oatpp::String> *params)
|
||||
: m_params(params)
|
||||
{}
|
||||
|
||||
oatpp::String StringTemplate::MapValueProvider::getValue(const Variable& variable, v_uint32 index) {
|
||||
(void) index;
|
||||
auto it = m_params->find(variable.name);
|
||||
if(it != m_params->end()) {
|
||||
return it->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StringTemplate::SingleValueProvider::SingleValueProvider(const oatpp::String& value)
|
||||
: m_value(value)
|
||||
{}
|
||||
|
||||
oatpp::String StringTemplate::SingleValueProvider::getValue(const Variable& variable, v_uint32 index) {
|
||||
(void) variable;
|
||||
(void) index;
|
||||
return m_value;
|
||||
}
|
||||
|
||||
StringTemplate::StringTemplate(const oatpp::String& text, std::vector<Variable>&& variables)
|
||||
: m_text(text)
|
||||
, m_variables(variables)
|
||||
@ -50,23 +82,24 @@ StringTemplate::StringTemplate(const oatpp::String& text, std::vector<Variable>&
|
||||
}
|
||||
}
|
||||
|
||||
void StringTemplate::format(stream::ConsistentOutputStream* stream, const std::vector<oatpp::String>& params) const {
|
||||
|
||||
if(params.size() != m_variables.size()) {
|
||||
throw std::runtime_error("[oatpp::data::share::StringTemplate::format()]: Error. Wrong number of arguments.");
|
||||
}
|
||||
void StringTemplate::format(stream::ConsistentOutputStream* stream, ValueProvider* valueProvider) const {
|
||||
|
||||
v_buff_size prevPos = 0;
|
||||
for(v_int32 i = 0; i < m_variables.size(); i++) {
|
||||
for(v_uint32 i = 0; i < m_variables.size(); i++) {
|
||||
|
||||
const auto& var = m_variables[i];
|
||||
const auto& param = params[i];
|
||||
const auto& value = valueProvider->getValue(var, i);
|
||||
|
||||
if(!value) {
|
||||
throw std::runtime_error("[oatpp::data::share::StringTemplate::format()]: "
|
||||
"Error. No value provided for the parameter name=" + var.name->std_str());
|
||||
}
|
||||
|
||||
if(prevPos < var.posStart) {
|
||||
stream->writeSimple(m_text->getData() + prevPos, var.posStart - prevPos);
|
||||
}
|
||||
|
||||
stream->writeSimple(param->getData(), param->getSize());
|
||||
stream->writeSimple(value->getData(), value->getSize());
|
||||
|
||||
prevPos = var.posEnd + 1;
|
||||
|
||||
@ -78,33 +111,19 @@ void StringTemplate::format(stream::ConsistentOutputStream* stream, const std::v
|
||||
|
||||
}
|
||||
|
||||
void StringTemplate::format(stream::ConsistentOutputStream* stream, const std::vector<oatpp::String>& params) const {
|
||||
VectorValueProvider vp(¶ms);
|
||||
format(stream, &vp);
|
||||
}
|
||||
|
||||
void StringTemplate::format(stream::ConsistentOutputStream* stream, const std::unordered_map<oatpp::String, oatpp::String>& params) const {
|
||||
MapValueProvider vp(¶ms);
|
||||
format(stream, &vp);
|
||||
}
|
||||
|
||||
v_buff_size prevPos = 0;
|
||||
for(v_int32 i = 0; i < m_variables.size(); i++) {
|
||||
|
||||
const auto& var = m_variables[i];
|
||||
auto paramIt = params.find(var.name);
|
||||
if(paramIt == params.end()) {
|
||||
throw std::runtime_error("[oatpp::data::share::StringTemplate::format()]: Error. Parameter not found. Name=" + var.name->std_str());
|
||||
}
|
||||
|
||||
const auto& param = paramIt->second;
|
||||
|
||||
if(prevPos < var.posStart) {
|
||||
stream->writeSimple(m_text->getData() + prevPos, var.posStart - prevPos);
|
||||
}
|
||||
|
||||
stream->writeSimple(param->getData(), param->getSize());
|
||||
|
||||
prevPos = var.posEnd + 1;
|
||||
|
||||
}
|
||||
|
||||
if(prevPos < m_text->getSize()) {
|
||||
stream->writeSimple(m_text->getData() + prevPos, m_text->getSize() - prevPos);
|
||||
}
|
||||
|
||||
void StringTemplate::format(stream::ConsistentOutputStream* stream, const oatpp::String& singleValue) const {
|
||||
SingleValueProvider vp(singleValue);
|
||||
format(stream, &vp);
|
||||
}
|
||||
|
||||
oatpp::String StringTemplate::format(const std::vector<oatpp::String>& params) const {
|
||||
@ -119,4 +138,14 @@ oatpp::String StringTemplate::format(const std::unordered_map<oatpp::String, oat
|
||||
return stream.toString();
|
||||
}
|
||||
|
||||
oatpp::String StringTemplate::format(const oatpp::String& singleValue) const {
|
||||
stream::BufferOutputStream stream;
|
||||
format(&stream, singleValue);
|
||||
return stream.toString();
|
||||
}
|
||||
|
||||
const std::vector<StringTemplate::Variable>& StringTemplate::getTemplateVariables() const {
|
||||
return m_variables;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
@ -33,13 +33,90 @@
|
||||
|
||||
namespace oatpp { namespace data { namespace share {
|
||||
|
||||
/**
|
||||
* String template.
|
||||
*/
|
||||
class StringTemplate {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Template variable.
|
||||
*/
|
||||
struct Variable {
|
||||
|
||||
/**
|
||||
* Position of the first char in the original template string.
|
||||
*/
|
||||
v_buff_size posStart;
|
||||
|
||||
/**
|
||||
* Position of the last char in the original template string.
|
||||
*/
|
||||
v_buff_size posEnd;
|
||||
|
||||
/**
|
||||
* Name of the template variable.
|
||||
*/
|
||||
oatpp::String name;
|
||||
|
||||
/**
|
||||
* Some auxiliary data.
|
||||
*/
|
||||
std::shared_ptr<void> extra;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Abstract template value provider.
|
||||
*/
|
||||
class ValueProvider {
|
||||
public:
|
||||
/**
|
||||
* Default virtual destructor.
|
||||
*/
|
||||
virtual ~ValueProvider() = default;
|
||||
|
||||
/**
|
||||
* Get value for variable.
|
||||
* @param variable - &l:StringTemplate::Variable;.
|
||||
* @param index - index of the variable in the template.
|
||||
* @return - value for the given variable.
|
||||
*/
|
||||
virtual oatpp::String getValue(const Variable& variable, v_uint32 index) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Provider of template variable-values based on the std::vector.
|
||||
*/
|
||||
class VectorValueProvider : public ValueProvider {
|
||||
private:
|
||||
const std::vector<oatpp::String>* m_params;
|
||||
public:
|
||||
VectorValueProvider(const std::vector<oatpp::String>* params);
|
||||
oatpp::String getValue(const Variable& variable, v_uint32 index) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Provider of template variable-values based on the std::unordered_map.
|
||||
*/
|
||||
class MapValueProvider : public ValueProvider {
|
||||
private:
|
||||
const std::unordered_map<oatpp::String, oatpp::String>* m_params;
|
||||
public:
|
||||
MapValueProvider(const std::unordered_map<oatpp::String, oatpp::String>* params);
|
||||
oatpp::String getValue(const Variable& variable, v_uint32 index) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Provider of template variable-values which returns the same value for all variables.
|
||||
*/
|
||||
class SingleValueProvider : public ValueProvider {
|
||||
private:
|
||||
oatpp::String m_value;
|
||||
public:
|
||||
SingleValueProvider(const oatpp::String& value);
|
||||
oatpp::String getValue(const Variable& variable, v_uint32 index) override;
|
||||
};
|
||||
|
||||
private:
|
||||
@ -47,14 +124,68 @@ private:
|
||||
std::vector<Variable> m_variables;
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param text - original template text.
|
||||
* @param variables - template variables.
|
||||
*/
|
||||
StringTemplate(const oatpp::String& text, std::vector<Variable>&& variables);
|
||||
|
||||
/**
|
||||
* Format template.
|
||||
* @param stream - stream to write result to.
|
||||
* @param valueProvider - &l:StringTemplate::ValueProvider;.
|
||||
*/
|
||||
void format(stream::ConsistentOutputStream* stream, ValueProvider* valueProvider) const;
|
||||
|
||||
/**
|
||||
* Format template using &l:StringTemplate::VectorValueProvider;.
|
||||
* @param stream - stream to write result to.
|
||||
* @param params - `std::vector<oatpp::String>`.
|
||||
*/
|
||||
void format(stream::ConsistentOutputStream* stream, const std::vector<oatpp::String>& params) const;
|
||||
|
||||
/**
|
||||
* Format template using &l:StringTemplate::MapValueProvider;.
|
||||
* @param stream - stream to write result to.
|
||||
* @param params - `std::unordered_map<oatpp::String, oatpp::String>`.
|
||||
*/
|
||||
void format(stream::ConsistentOutputStream* stream, const std::unordered_map<oatpp::String, oatpp::String>& params) const;
|
||||
|
||||
/**
|
||||
* Format template using &l:StringTemplate::SingleValueProvider;.
|
||||
* @param stream - stream to write result to.
|
||||
* @param singleValue - value.
|
||||
*/
|
||||
void format(stream::ConsistentOutputStream* stream, const oatpp::String& singleValue) const;
|
||||
|
||||
/**
|
||||
* Format template using &l:StringTemplate::VectorValueProvider;.
|
||||
* @param params - `std::vector<oatpp::String>`.
|
||||
* @return - resultant string.
|
||||
*/
|
||||
oatpp::String format(const std::vector<oatpp::String>& params) const;
|
||||
|
||||
/**
|
||||
* Format template using &l:StringTemplate::MapValueProvider;.
|
||||
* @param params - `std::unordered_map<oatpp::String, oatpp::String>`.
|
||||
* @return - resultant string.
|
||||
*/
|
||||
oatpp::String format(const std::unordered_map<oatpp::String, oatpp::String>& params) const;
|
||||
|
||||
/**
|
||||
* Format template using &l:StringTemplate::SingleValueProvider;.
|
||||
* @param singleValue - value.
|
||||
* @return - resultant string.
|
||||
*/
|
||||
oatpp::String format(const oatpp::String& singleValue) const;
|
||||
|
||||
/**
|
||||
* Get all template variables.
|
||||
* @return - `std::vector` of &l:StringTemplate::Variable;.
|
||||
*/
|
||||
const std::vector<Variable>& getTemplateVariables() const;
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
@ -35,7 +35,7 @@
|
||||
namespace oatpp { namespace db {
|
||||
|
||||
class Client {
|
||||
private:
|
||||
protected:
|
||||
std::shared_ptr<Executor> m_executor;
|
||||
public:
|
||||
|
||||
@ -50,17 +50,6 @@ public:
|
||||
// "DELETE FROM user WHERE userId=:userId",
|
||||
// PARAM(String, userId))
|
||||
|
||||
oatpp::data::share::StringTemplate Z_QUERY_TEMPLATE_getUserById =
|
||||
m_executor->parseQueryTemplate("SELECT * FROM user WHERE userId=:userId");
|
||||
|
||||
oatpp::db::QueryResult getUserById(const oatpp::String& userId) {
|
||||
std::unordered_map<oatpp::String, oatpp::Any> __params;
|
||||
__params["userId"] = userId;
|
||||
return m_executor->execute(Z_QUERY_TEMPLATE_getUserById, __params);
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
}}
|
||||
|
@ -35,7 +35,7 @@ void StringTemplateTest::onRun() {
|
||||
{
|
||||
OATPP_LOGI(TAG, "Case1 ...");
|
||||
StringTemplate t("{} World!", {{0, 1, "p1"}});
|
||||
auto result = t.format({"Hello"});
|
||||
auto result = t.format({oatpp::String("Hello")});
|
||||
OATPP_ASSERT(result == "Hello World!");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
@ -51,7 +51,7 @@ void StringTemplateTest::onRun() {
|
||||
{
|
||||
OATPP_LOGI(TAG, "Case3 ...");
|
||||
StringTemplate t("Hello {}", {{6, 7, "p1"}});
|
||||
auto result = t.format({"World!"});
|
||||
auto result = t.format({oatpp::String("World!")});
|
||||
OATPP_ASSERT(result == "Hello World!");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
@ -67,7 +67,7 @@ void StringTemplateTest::onRun() {
|
||||
{
|
||||
OATPP_LOGI(TAG, "Case5 ...");
|
||||
StringTemplate t("Hello {} World!", {{6, 7, "p1"}});
|
||||
auto result = t.format({"My"});
|
||||
auto result = t.format({oatpp::String("My")});
|
||||
OATPP_ASSERT(result == "Hello My World!");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
@ -96,6 +96,28 @@ void StringTemplateTest::onRun() {
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Case9 ...");
|
||||
StringTemplate t("? ? ?", {{0, 0, "p1"}, {2, 2, "p2"}, {4, 4, "p3"}});
|
||||
auto result = t.format("A");
|
||||
OATPP_ASSERT(result == "A A A");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Case10 ...");
|
||||
StringTemplate t("? ? ?",
|
||||
{
|
||||
{0, 0, "p1", std::make_shared<oatpp::base::Countable>()},
|
||||
{2, 2, "p2", std::make_shared<oatpp::base::Countable>()},
|
||||
{4, 4, "p3", std::make_shared<oatpp::base::Countable>()}
|
||||
}
|
||||
);
|
||||
auto result = t.format("(A)");
|
||||
OATPP_ASSERT(result == "(A) (A) (A)");
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}}}
|
||||
|
Loading…
Reference in New Issue
Block a user