mirror of
https://gitee.com/zyjblog/oatpp.git
synced 2025-01-03 05:22:24 +08:00
mapping::Tree: better tests, improved attributes, improved interface of oatpp::Tree
This commit is contained in:
parent
917dd454ce
commit
6765c3e591
@ -20,7 +20,9 @@
|
|||||||
|
|
||||||
**News**
|
**News**
|
||||||
|
|
||||||
- ⚠️ Attention! Oat++ main repo is bumping it's version to 1.4.0. While 1.4.0 is **IN DEVELOPMENT** use `1.3.0-latest` tag.
|
- ⚠️ Attention! Oat++ main repo is bumping its version to 1.4.0. While 1.4.0 is **IN DEVELOPMENT** use `1.3.0-latest` tag.
|
||||||
|
- Follow the [changelog](https://github.com/oatpp/oatpp/blob/master/changelog/1.4.0.md) for news and features in version `1.4.0`.
|
||||||
|
- Consider supporting Oat++ via the [GitHub sponsors](https://github.com/sponsors/oatpp) page.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@ Contents:
|
|||||||
|
|
||||||
- [URL Encoder And Decoder](#url-encoder-and-decoder)
|
- [URL Encoder And Decoder](#url-encoder-and-decoder)
|
||||||
- [Introduce async::ConditionVariable](#async-condition-variable)
|
- [Introduce async::ConditionVariable](#async-condition-variable)
|
||||||
|
- [oatpp::Tree](#oatpptree)
|
||||||
|
- [Remapper](#remapper)
|
||||||
- [Restructuring](#restructuring)
|
- [Restructuring](#restructuring)
|
||||||
|
|
||||||
|
|
||||||
@ -49,6 +51,61 @@ OATPP_ASSERT(decoded == data)
|
|||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## oatpp::Tree
|
||||||
|
|
||||||
|
New mapping-enabled type `oatpp::Tree` for flexible data access.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
ENDPOINT("POST", "users", createUser,
|
||||||
|
BODY_DTO(oatpp::Tree, user))
|
||||||
|
{
|
||||||
|
oatpp::String name = user["name"];
|
||||||
|
v_uint16 age = user["age"];
|
||||||
|
|
||||||
|
auto& subs = user["subscriptions"].getVector();
|
||||||
|
for(auto& s : subs) {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Any node of oatpp::Tree can be mapped to DTO or to any mapping-enabled oatpp type - see [Remapper](#remapper)
|
||||||
|
|
||||||
|
## Remapper
|
||||||
|
|
||||||
|
`oatpp::data::mapping::Remapper`.
|
||||||
|
|
||||||
|
Remapper can be user to remap any oatpp type to any oatpp type.
|
||||||
|
UnorderedFields can be mapped to DTOs, DTOs to vectors of values, vector items to other DTOs, DTOs to Trees, etc...
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
class User : public oatpp::DTO {
|
||||||
|
|
||||||
|
DTO_INIT(User, DTO)
|
||||||
|
|
||||||
|
DTO_FIELD(String, name);
|
||||||
|
DTO_FIELD(UInt32, age);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
oatpp::data::mapping::Remapper remapper;
|
||||||
|
|
||||||
|
auto user = User::createShared();
|
||||||
|
user->name = "Jane";
|
||||||
|
user->age = "25";
|
||||||
|
|
||||||
|
auto tree = remapper.remap<oatpp::Tree>(user); // remap to tree
|
||||||
|
auto fields = remapper.remap<oatpp::Fields<oatpp::Tree>>(user); // remap to Fields
|
||||||
|
auto otherDto = remapper.remap<oatpp::Object<OtherDto>>(user); // remap to OtherDto
|
||||||
|
auto values = remapper.remap<oatpp::Vector<oatpp::Tree>>(user); // remap to Vector
|
||||||
|
|
||||||
|
oatpp::String name = values[0];
|
||||||
|
v_uint32 age = values[1];
|
||||||
|
```
|
||||||
|
|
||||||
## Restructuring
|
## Restructuring
|
||||||
|
|
||||||
### Files
|
### Files
|
||||||
|
@ -26,9 +26,9 @@
|
|||||||
|
|
||||||
namespace oatpp { namespace data { namespace mapping {
|
namespace oatpp { namespace data { namespace mapping {
|
||||||
|
|
||||||
oatpp::Void ObjectRemapper::mapTree(const Tree* tree, const oatpp::Type* toType, ErrorStack& errorStack) const {
|
oatpp::Void ObjectRemapper::remap(const Tree& tree, const oatpp::Type* toType, ErrorStack& errorStack) const {
|
||||||
TreeToObjectMapper::State state;
|
TreeToObjectMapper::State state;
|
||||||
state.tree = tree;
|
state.tree = std::addressof(tree);
|
||||||
state.config = &m_treeToObjectConfig;
|
state.config = &m_treeToObjectConfig;
|
||||||
const auto & result = m_treeToObjectMapper.map(state, toType);
|
const auto & result = m_treeToObjectMapper.map(state, toType);
|
||||||
if(!state.errorStack.empty()) {
|
if(!state.errorStack.empty()) {
|
||||||
@ -40,10 +40,14 @@ oatpp::Void ObjectRemapper::mapTree(const Tree* tree, const oatpp::Type* toType,
|
|||||||
|
|
||||||
oatpp::Void ObjectRemapper::remap(const oatpp::Void& polymorph, const oatpp::Type* toType, ErrorStack& errorStack) const {
|
oatpp::Void ObjectRemapper::remap(const oatpp::Void& polymorph, const oatpp::Type* toType, ErrorStack& errorStack) const {
|
||||||
|
|
||||||
|
if(polymorph == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/* if polymorph is a Tree - we can map it right away */
|
/* if polymorph is a Tree - we can map it right away */
|
||||||
if(polymorph.getValueType() == oatpp::Tree::Class::getType()) {
|
if(polymorph.getValueType() == oatpp::Tree::Class::getType()) {
|
||||||
auto tree = static_cast<const Tree*>(polymorph.get());
|
auto tree = static_cast<const Tree*>(polymorph.get());
|
||||||
return mapTree(tree, toType, errorStack);
|
return remap(*tree, toType, errorStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
Tree tree;
|
Tree tree;
|
||||||
@ -64,7 +68,7 @@ oatpp::Void ObjectRemapper::remap(const oatpp::Void& polymorph, const oatpp::Typ
|
|||||||
return oatpp::Tree(std::move(tree));
|
return oatpp::Tree(std::move(tree));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mapTree(&tree, toType, errorStack);
|
return remap(tree, toType, errorStack);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,8 +33,6 @@
|
|||||||
namespace oatpp { namespace data { namespace mapping {
|
namespace oatpp { namespace data { namespace mapping {
|
||||||
|
|
||||||
class ObjectRemapper {
|
class ObjectRemapper {
|
||||||
protected:
|
|
||||||
oatpp::Void mapTree(const Tree* tree, const oatpp::Type* toType, ErrorStack& errorStack) const;
|
|
||||||
protected:
|
protected:
|
||||||
ObjectToTreeMapper::Config m_objectToTreeConfig;
|
ObjectToTreeMapper::Config m_objectToTreeConfig;
|
||||||
TreeToObjectMapper::Config m_treeToObjectConfig;
|
TreeToObjectMapper::Config m_treeToObjectConfig;
|
||||||
@ -45,6 +43,25 @@ public:
|
|||||||
ObjectRemapper() = default;
|
ObjectRemapper() = default;
|
||||||
virtual ~ObjectRemapper() = default;
|
virtual ~ObjectRemapper() = default;
|
||||||
|
|
||||||
|
oatpp::Void remap(const Tree& tree, const oatpp::Type* toType, ErrorStack& errorStack) const;
|
||||||
|
|
||||||
|
template<class Wrapper>
|
||||||
|
Wrapper remap(const Tree& tree, ErrorStack& errorStack) const {
|
||||||
|
auto toType = Wrapper::Class::getType();
|
||||||
|
return remap(tree, toType, errorStack).template cast<Wrapper>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Wrapper>
|
||||||
|
Wrapper remap(const Tree& tree) const {
|
||||||
|
auto toType = Wrapper::Class::getType();
|
||||||
|
ErrorStack errorStack;
|
||||||
|
const auto& result = remap(tree, toType, errorStack).template cast<Wrapper>();
|
||||||
|
if(!errorStack.empty()) {
|
||||||
|
throw MappingError(std::move(errorStack));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
oatpp::Void remap(const oatpp::Void& polymorph, const oatpp::Type* toType, ErrorStack& errorStack) const;
|
oatpp::Void remap(const oatpp::Void& polymorph, const oatpp::Type* toType, ErrorStack& errorStack) const;
|
||||||
|
|
||||||
template<class Wrapper>
|
template<class Wrapper>
|
||||||
|
@ -36,8 +36,10 @@ Tree::Attributes::Attributes()
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
Tree::Attributes::Attributes(const Attributes& other)
|
Tree::Attributes::Attributes(const Attributes& other)
|
||||||
: m_attributes(other.m_attributes != nullptr ? new std::unordered_map<type::String, type::String>(*other.m_attributes) : nullptr)
|
: Attributes()
|
||||||
{}
|
{
|
||||||
|
operator=(other);
|
||||||
|
}
|
||||||
|
|
||||||
Tree::Attributes::Attributes(Attributes&& other) noexcept
|
Tree::Attributes::Attributes(Attributes&& other) noexcept
|
||||||
: m_attributes(other.m_attributes)
|
: m_attributes(other.m_attributes)
|
||||||
@ -46,37 +48,101 @@ Tree::Attributes::Attributes(Attributes&& other) noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
Tree::Attributes& Tree::Attributes::operator = (const Attributes& other) {
|
Tree::Attributes& Tree::Attributes::operator = (const Attributes& other) {
|
||||||
|
|
||||||
if(other.m_attributes) {
|
if(other.m_attributes) {
|
||||||
|
|
||||||
if(m_attributes) {
|
if(m_attributes) {
|
||||||
*m_attributes = *other.m_attributes;
|
*m_attributes = *other.m_attributes;
|
||||||
} else {
|
} else {
|
||||||
m_attributes = new std::unordered_map<type::String, type::String>(*other.m_attributes);
|
m_attributes = new Attrs(*other.m_attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(auto & po : m_attributes->order){
|
||||||
|
po.second = &m_attributes->map.at(po.first.lock());
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
delete m_attributes;
|
delete m_attributes;
|
||||||
m_attributes = nullptr;
|
m_attributes = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tree::Attributes& Tree::Attributes::operator = (Attributes&& other) noexcept {
|
Tree::Attributes& Tree::Attributes::operator = (Attributes&& other) noexcept {
|
||||||
|
|
||||||
delete m_attributes;
|
delete m_attributes;
|
||||||
|
|
||||||
m_attributes = other.m_attributes;
|
m_attributes = other.m_attributes;
|
||||||
other.m_attributes = nullptr;
|
other.m_attributes = nullptr;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tree::Attributes::~Attributes() {
|
Tree::Attributes::~Attributes() {
|
||||||
delete m_attributes;
|
delete m_attributes;
|
||||||
|
m_attributes = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tree::Attributes::initAttributes() {
|
||||||
|
if(m_attributes == nullptr) {
|
||||||
|
m_attributes = new Attrs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type::String& Tree::Attributes::operator [] (const type::String& key) {
|
||||||
|
initAttributes();
|
||||||
|
auto it = m_attributes->map.find(key);
|
||||||
|
if(it == m_attributes->map.end()) {
|
||||||
|
auto& result = m_attributes->map[key];
|
||||||
|
m_attributes->order.emplace_back(key.getPtr(), &result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const type::String& Tree::Attributes::operator [] (const type::String& key) const {
|
||||||
|
if(m_attributes != nullptr) {
|
||||||
|
auto it = m_attributes->map.find(key);
|
||||||
|
if (it != m_attributes->map.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw std::runtime_error("[oatpp::data::mapping::Tree::Attributes::operator []]: const operator[] can't add items.");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<type::String, std::reference_wrapper<type::String>> Tree::Attributes::operator [] (v_uint64 index) {
|
||||||
|
if(m_attributes != nullptr) {
|
||||||
|
auto &item = m_attributes->order.at(index);
|
||||||
|
return {item.first.lock(), *item.second};
|
||||||
|
}
|
||||||
|
throw std::runtime_error("[oatpp::data::mapping::Tree::Attributes::operator []]: const operator[] can't get item - empty attributes.");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<type::String, std::reference_wrapper<const type::String>> Tree::Attributes::operator [] (v_uint64 index) const {
|
||||||
|
if(m_attributes != nullptr) {
|
||||||
|
auto &item = m_attributes->order.at(index);
|
||||||
|
return {item.first.lock(), *item.second};
|
||||||
|
}
|
||||||
|
throw std::runtime_error("[oatpp::data::mapping::Tree::Attributes::operator []]: const operator[] can't get item - empty attributes.");
|
||||||
|
}
|
||||||
|
|
||||||
|
type::String Tree::Attributes::get(const type::String& key) const {
|
||||||
|
if(m_attributes == nullptr) return nullptr;
|
||||||
|
auto it = m_attributes->map.find(key);
|
||||||
|
if(it != m_attributes->map.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Tree::Attributes::empty() const {
|
bool Tree::Attributes::empty() const {
|
||||||
return m_attributes == nullptr || m_attributes->empty();
|
return m_attributes == nullptr || m_attributes->map.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
v_uint64 Tree::Attributes::size() const {
|
v_uint64 Tree::Attributes::size() const {
|
||||||
if(m_attributes) {
|
if(m_attributes) {
|
||||||
return m_attributes->size();
|
return m_attributes->map.size();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -725,13 +791,9 @@ TreeMap::TreeMap(TreeMap&& other) noexcept {
|
|||||||
|
|
||||||
TreeMap& TreeMap::operator = (const TreeMap& other) {
|
TreeMap& TreeMap::operator = (const TreeMap& other) {
|
||||||
m_map = other.m_map;
|
m_map = other.m_map;
|
||||||
m_order.resize(other.m_order.size());
|
m_order = other.m_order;
|
||||||
for(v_uint64 i = 0; i < other.m_order.size(); i ++) {
|
for(auto & po : m_order){
|
||||||
auto& po = other.m_order[i];
|
po.second = &m_map.at(po.first.lock());
|
||||||
auto& pt = m_order[i];
|
|
||||||
pt.first = po.first;
|
|
||||||
|
|
||||||
pt.second = &m_map.at(po.first.lock());
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,14 @@ public:
|
|||||||
|
|
||||||
class Attributes {
|
class Attributes {
|
||||||
private:
|
private:
|
||||||
std::unordered_map<type::String, type::String>* m_attributes;
|
struct Attrs {
|
||||||
|
std::unordered_map<type::String, type::String> map;
|
||||||
|
std::vector<std::pair<std::weak_ptr<std::string>, type::String*>> order;
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
void initAttributes();
|
||||||
|
private:
|
||||||
|
Attrs* m_attributes;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Attributes();
|
Attributes();
|
||||||
@ -84,8 +91,15 @@ public:
|
|||||||
|
|
||||||
~Attributes();
|
~Attributes();
|
||||||
|
|
||||||
bool empty() const;
|
type::String& operator [] (const type::String& key);
|
||||||
|
const type::String& operator [] (const type::String& key) const;
|
||||||
|
|
||||||
|
std::pair<type::String, std::reference_wrapper<type::String>> operator [] (v_uint64 index);
|
||||||
|
std::pair<type::String, std::reference_wrapper<const type::String>> operator [] (v_uint64 index) const;
|
||||||
|
|
||||||
|
type::String get(const type::String& key) const;
|
||||||
|
|
||||||
|
bool empty() const;
|
||||||
v_uint64 size() const;
|
v_uint64 size() const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -435,6 +435,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
typedef oatpp::data::type::Void Void;
|
typedef oatpp::data::type::Void Void;
|
||||||
typedef oatpp::data::type::Any Any;
|
typedef oatpp::data::type::Any Any;
|
||||||
|
typedef oatpp::data::type::Tree Tree;
|
||||||
typedef oatpp::data::type::String String;
|
typedef oatpp::data::type::String String;
|
||||||
typedef oatpp::data::type::Int8 Int8;
|
typedef oatpp::data::type::Int8 Int8;
|
||||||
typedef oatpp::data::type::UInt8 UInt8;
|
typedef oatpp::data::type::UInt8 UInt8;
|
||||||
|
@ -123,6 +123,27 @@ bool Tree::operator != (const Tree& other) const {
|
|||||||
return !operator == (other);
|
return !operator == (other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mapping::Tree* Tree::operator->() {
|
||||||
|
if(!m_ptr) {
|
||||||
|
m_ptr = std::make_shared<mapping::Tree>();
|
||||||
|
}
|
||||||
|
return m_ptr.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
mapping::Tree* Tree::operator->() const {
|
||||||
|
if(!m_ptr) {
|
||||||
|
throw std::runtime_error("[oatpp::data::type::Tree::operator ->()]: null-pointer exception");
|
||||||
|
}
|
||||||
|
return m_ptr.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
mapping::Tree& Tree::operator*() {
|
||||||
|
if(!m_ptr) {
|
||||||
|
m_ptr = std::make_shared<mapping::Tree>();
|
||||||
|
}
|
||||||
|
return *m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
const mapping::Tree& Tree::operator*() const {
|
const mapping::Tree& Tree::operator*() const {
|
||||||
if(!m_ptr) {
|
if(!m_ptr) {
|
||||||
throw std::runtime_error("[oatpp::data::type::Tree::operator *()]: null-pointer exception");
|
throw std::runtime_error("[oatpp::data::type::Tree::operator *()]: null-pointer exception");
|
||||||
@ -130,12 +151,32 @@ const mapping::Tree& Tree::operator*() const {
|
|||||||
return *m_ptr;
|
return *m_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapping::Tree& Tree::operator*() {
|
mapping::Tree& Tree::operator [] (const String& key) {
|
||||||
if(!m_ptr) {
|
if(!m_ptr) {
|
||||||
throw std::runtime_error("[oatpp::data::type::Tree::operator *()]: null-pointer exception");
|
m_ptr = std::make_shared<mapping::Tree>();
|
||||||
}
|
}
|
||||||
return *m_ptr;
|
return (*m_ptr)[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mapping::Tree& Tree::operator [] (const String& key) const {
|
||||||
|
if(!m_ptr) {
|
||||||
|
throw std::runtime_error("[oatpp::data::type::Tree::operator []]: null-pointer exception");
|
||||||
|
}
|
||||||
|
return (*m_ptr)[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
mapping::Tree& Tree::operator [] (v_uint64 index) {
|
||||||
|
if(!m_ptr) {
|
||||||
|
m_ptr = std::make_shared<mapping::Tree>();
|
||||||
|
}
|
||||||
|
return (*m_ptr)[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapping::Tree& Tree::operator [] (v_uint64 index) const {
|
||||||
|
if(!m_ptr) {
|
||||||
|
throw std::runtime_error("[oatpp::data::type::Tree::operator []]: null-pointer exception");
|
||||||
|
}
|
||||||
|
return (*m_ptr)[index];
|
||||||
|
}
|
||||||
|
|
||||||
}}}
|
}}}
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#define oatpp_data_type_Tree_hpp
|
#define oatpp_data_type_Tree_hpp
|
||||||
|
|
||||||
#include "./Type.hpp"
|
#include "./Type.hpp"
|
||||||
|
#include "./Primitive.hpp"
|
||||||
|
|
||||||
namespace oatpp { namespace data { namespace mapping {
|
namespace oatpp { namespace data { namespace mapping {
|
||||||
|
|
||||||
@ -108,8 +109,17 @@ public:
|
|||||||
bool operator == (const Tree& other) const;
|
bool operator == (const Tree& other) const;
|
||||||
bool operator != (const Tree& other) const;
|
bool operator != (const Tree& other) const;
|
||||||
|
|
||||||
const mapping::Tree& operator*() const;
|
mapping::Tree* operator->();
|
||||||
|
mapping::Tree* operator->() const;
|
||||||
|
|
||||||
mapping::Tree& operator*();
|
mapping::Tree& operator*();
|
||||||
|
const mapping::Tree& operator*() const;
|
||||||
|
|
||||||
|
mapping::Tree& operator [] (const String& key);
|
||||||
|
const mapping::Tree& operator [] (const String& key) const;
|
||||||
|
|
||||||
|
mapping::Tree& operator [] (v_uint64 index);
|
||||||
|
const mapping::Tree& operator [] (v_uint64 index) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -247,8 +247,6 @@ void runTests() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -168,6 +168,57 @@ void ObjectRemapperTest::onRun() {
|
|||||||
OATPP_ASSERT(vec[4] == nullptr)
|
OATPP_ASSERT(vec[4] == nullptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
OATPP_LOGD(TAG, "Remap tree fragments")
|
||||||
|
|
||||||
|
Tree tree;
|
||||||
|
tree.setVector(3);
|
||||||
|
|
||||||
|
tree[0]["field_1"] = "val1";
|
||||||
|
tree[0]["field_2"] = "val2";
|
||||||
|
|
||||||
|
tree[1]["field_1"] = "val1.2";
|
||||||
|
tree[1]["field_2"] = "val2.2";
|
||||||
|
|
||||||
|
tree[2]["field_1"] = "val1.3";
|
||||||
|
tree[2]["field_2"] = "val2.3";
|
||||||
|
|
||||||
|
{
|
||||||
|
auto map = remapper.remap<oatpp::UnorderedFields<String>>(tree[0]);
|
||||||
|
OATPP_ASSERT(map->size() == 2)
|
||||||
|
OATPP_ASSERT(map["field_1"] == "val1")
|
||||||
|
OATPP_ASSERT(map["field_2"] == "val2")
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto map = remapper.remap<oatpp::UnorderedFields<String>>(tree[1]);
|
||||||
|
OATPP_ASSERT(map->size() == 2)
|
||||||
|
OATPP_ASSERT(map["field_1"] == "val1.2")
|
||||||
|
OATPP_ASSERT(map["field_2"] == "val2.2")
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto map = remapper.remap<oatpp::UnorderedFields<String>>(tree[2]);
|
||||||
|
OATPP_ASSERT(map->size() == 2)
|
||||||
|
OATPP_ASSERT(map["field_1"] == "val1.3")
|
||||||
|
OATPP_ASSERT(map["field_2"] == "val2.3")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
oatpp::Tree tree;
|
||||||
|
OATPP_ASSERT(tree == nullptr)
|
||||||
|
|
||||||
|
OATPP_ASSERT(tree->isUndefined()) // implicitly initialized
|
||||||
|
OATPP_ASSERT(tree != nullptr)
|
||||||
|
|
||||||
|
tree["hello"] = "world";
|
||||||
|
std::cout << *tree->debugPrint() << std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}}}
|
}}}
|
||||||
|
@ -36,6 +36,8 @@ namespace {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
void testTreeValue(T value) {
|
void testTreeValue(T value) {
|
||||||
|
|
||||||
|
OATPP_LOGD("TEST", "Test value retrieval for '%s'", Tree::NodePrimitiveType<T>::name)
|
||||||
|
|
||||||
Tree node;
|
Tree node;
|
||||||
|
|
||||||
//node.setValue<T>(value);
|
//node.setValue<T>(value);
|
||||||
@ -70,6 +72,7 @@ void TreeTest::onRun() {
|
|||||||
testTreeValue<v_float64>(16);
|
testTreeValue<v_float64>(16);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
OATPP_LOGD(TAG, "Case 1")
|
||||||
Tree node;
|
Tree node;
|
||||||
oatpp::String original = "Hello World!";
|
oatpp::String original = "Hello World!";
|
||||||
node.setString(original);
|
node.setString(original);
|
||||||
@ -79,6 +82,7 @@ void TreeTest::onRun() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
OATPP_LOGD(TAG, "Case 2")
|
||||||
Tree node1;
|
Tree node1;
|
||||||
Tree node2;
|
Tree node2;
|
||||||
|
|
||||||
@ -93,6 +97,7 @@ void TreeTest::onRun() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
OATPP_LOGD(TAG, "Case 3")
|
||||||
Tree node1;
|
Tree node1;
|
||||||
Tree node2;
|
Tree node2;
|
||||||
|
|
||||||
@ -105,6 +110,7 @@ void TreeTest::onRun() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
OATPP_LOGD(TAG, "Case 4")
|
||||||
std::vector<Tree> originalVector(10);
|
std::vector<Tree> originalVector(10);
|
||||||
for(v_uint32 i = 0; i < 10; i ++) {
|
for(v_uint32 i = 0; i < 10; i ++) {
|
||||||
originalVector.at(i).setValue(i);
|
originalVector.at(i).setValue(i);
|
||||||
@ -132,6 +138,7 @@ void TreeTest::onRun() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
OATPP_LOGD(TAG, "Case 5")
|
||||||
TreeMap originalMap;
|
TreeMap originalMap;
|
||||||
for(v_uint32 i = 0; i < 10; i ++) {
|
for(v_uint32 i = 0; i < 10; i ++) {
|
||||||
originalMap["node_" + utils::Conversion::int32ToStr(static_cast<v_int32>(i))].setValue(i);
|
originalMap["node_" + utils::Conversion::int32ToStr(static_cast<v_int32>(i))].setValue(i);
|
||||||
@ -156,6 +163,7 @@ void TreeTest::onRun() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
OATPP_LOGD(TAG, "Case 6")
|
||||||
Tree article;
|
Tree article;
|
||||||
oatpp::Tree ot;
|
oatpp::Tree ot;
|
||||||
|
|
||||||
@ -176,6 +184,120 @@ void TreeTest::onRun() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
OATPP_LOGD(TAG, "Attributes Case 1")
|
||||||
|
OATPP_LOGD(TAG, "size of Tree::Attributes='%lu'", sizeof(Tree::Attributes))
|
||||||
|
|
||||||
|
Tree::Attributes attr;
|
||||||
|
|
||||||
|
attr["key1"] = "value1";
|
||||||
|
attr["key1"] = "value1.2";
|
||||||
|
attr["key2"] = "value2";
|
||||||
|
|
||||||
|
OATPP_ASSERT(attr.size() == 2)
|
||||||
|
|
||||||
|
OATPP_ASSERT(attr["key1"] == "value1.2")
|
||||||
|
OATPP_ASSERT(attr["key2"] == "value2")
|
||||||
|
OATPP_ASSERT(attr["key3"] == nullptr) // key3 added
|
||||||
|
|
||||||
|
OATPP_ASSERT(attr.size() == 3)
|
||||||
|
|
||||||
|
OATPP_ASSERT(attr[0].second.get() == "value1.2")
|
||||||
|
OATPP_ASSERT(attr[1].second.get() == "value2")
|
||||||
|
OATPP_ASSERT(attr[2].second.get() == nullptr)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
OATPP_LOGD(TAG, "Attributes Case 2")
|
||||||
|
|
||||||
|
Tree::Attributes attr1;
|
||||||
|
Tree::Attributes attr2;
|
||||||
|
|
||||||
|
attr1["key1"] = "value1";
|
||||||
|
attr1["key2"] = "value2";
|
||||||
|
attr1["key3"] = nullptr;
|
||||||
|
|
||||||
|
attr2["key1"] = "v1";
|
||||||
|
attr2["key2"] = "v2";
|
||||||
|
|
||||||
|
attr2 = attr1;
|
||||||
|
|
||||||
|
attr1["key1"] = "1";
|
||||||
|
attr1["key2"] = "2";
|
||||||
|
attr1["key3"] = "3";
|
||||||
|
|
||||||
|
OATPP_ASSERT(attr1[0].second.get() == "1")
|
||||||
|
OATPP_ASSERT(attr1[1].second.get() == "2")
|
||||||
|
OATPP_ASSERT(attr1[2].second.get() == "3")
|
||||||
|
|
||||||
|
OATPP_ASSERT(attr1["key1"] == "1")
|
||||||
|
OATPP_ASSERT(attr1["key2"] == "2")
|
||||||
|
OATPP_ASSERT(attr1["key3"] == "3")
|
||||||
|
|
||||||
|
OATPP_ASSERT(attr2[0].second.get() == "value1")
|
||||||
|
OATPP_ASSERT(attr2[1].second.get() == "value2")
|
||||||
|
OATPP_ASSERT(attr2[2].second.get() == nullptr)
|
||||||
|
|
||||||
|
OATPP_ASSERT(attr2["key1"] == "value1")
|
||||||
|
OATPP_ASSERT(attr2["key2"] == "value2")
|
||||||
|
OATPP_ASSERT(attr2["key3"] == nullptr)
|
||||||
|
|
||||||
|
Tree::Attributes attr3;
|
||||||
|
attr2 = attr3;
|
||||||
|
|
||||||
|
OATPP_ASSERT(attr2.empty())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
OATPP_LOGD(TAG, "Attributes Case 3")
|
||||||
|
|
||||||
|
Tree tree1;
|
||||||
|
Tree tree2;
|
||||||
|
|
||||||
|
tree1 = "hello";
|
||||||
|
tree2 = "world";
|
||||||
|
|
||||||
|
tree1.attributes()["key1"] = "value1";
|
||||||
|
tree1.attributes()["key2"] = "value2";
|
||||||
|
tree1.attributes()["key3"] = nullptr;
|
||||||
|
|
||||||
|
tree2.attributes()["key1"] = "v1";
|
||||||
|
tree2.attributes()["key2"] = "v2";
|
||||||
|
|
||||||
|
tree2 = tree1;
|
||||||
|
|
||||||
|
tree1.attributes()["key1"] = "1";
|
||||||
|
tree1.attributes()["key2"] = "2";
|
||||||
|
tree1.attributes()["key3"] = "3";
|
||||||
|
|
||||||
|
OATPP_ASSERT(tree1.attributes()[0].second.get() == "1")
|
||||||
|
OATPP_ASSERT(tree1.attributes()[1].second.get() == "2")
|
||||||
|
OATPP_ASSERT(tree1.attributes()[2].second.get() == "3")
|
||||||
|
|
||||||
|
OATPP_ASSERT(tree1.attributes()["key1"] == "1")
|
||||||
|
OATPP_ASSERT(tree1.attributes()["key2"] == "2")
|
||||||
|
OATPP_ASSERT(tree1.attributes()["key3"] == "3")
|
||||||
|
|
||||||
|
OATPP_ASSERT(tree2.attributes()[0].second.get() == "value1")
|
||||||
|
OATPP_ASSERT(tree2.attributes()[1].second.get() == "value2")
|
||||||
|
OATPP_ASSERT(tree2.attributes()[2].second.get() == nullptr)
|
||||||
|
|
||||||
|
OATPP_ASSERT(tree2.attributes()["key1"] == "value1")
|
||||||
|
OATPP_ASSERT(tree2.attributes()["key2"] == "value2")
|
||||||
|
OATPP_ASSERT(tree2.attributes()["key3"] == nullptr)
|
||||||
|
|
||||||
|
Tree tree3;
|
||||||
|
tree2 = tree3;
|
||||||
|
|
||||||
|
OATPP_ASSERT(tree2.attributes().empty())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}}}
|
}}}
|
||||||
|
Loading…
Reference in New Issue
Block a user