Skip to content

Commit

Permalink
feat: push_back for element
Browse files Browse the repository at this point in the history
  • Loading branch information
Adamska1008 committed Sep 6, 2024
1 parent 1a4477b commit 17020e2
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 49 deletions.
13 changes: 13 additions & 0 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@ std::vector<element> children = root.elems();
std::vector<element> children = root.elems("child");
```

#### Insertion

```C++
using namespace myxml;
element root("root");
element child("child");
root.push_back(child);
REQUIRE(root.first_elem().name() == "child");
element next("next");
root.push_front(next);
REQUIRE(root.first_elem().name() == "next");
```
### Text
```C++
Expand Down
71 changes: 45 additions & 26 deletions include/myxml/element.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,42 @@
#include <optional>
#include <string>
#include <map>
#include <type_traits>

#include "myxml/text.hpp"
#include "myxml/cdata.hpp"
#include "myxml/printable.hpp"
#include "myxml/interface.hpp"

namespace myxml
{

struct element_impl : public composite_node // public std::enable_shared_from_this<Element>, public Node
{
public:
std::string _name;
std::map<std::string, std::string, std::less<>> _attributes;

/* Set initializer as private to avoid using Element without share_ptr*/

virtual ~element_impl() = default;
explicit element_impl(std::string_view name);
element_impl() = default;
/* Builder */
// Wraps creating shared_ptr
static std::shared_ptr<element_impl> _new(std::string_view name);
static std::shared_ptr<element_impl> _new();
static std::shared_ptr<element_impl> parse(std::string_view buf);
static std::shared_ptr<element_impl> load(std::string_view path);

/* Manipulate */
void extend_attributes(std::map<std::string, std::string>);
std::string &operator[](const std::string &);

/* Implement Exportable */
virtual void print(std::ostream &) const override;
};

enum class ClosingType
{
Closed,
Expand All @@ -25,7 +53,7 @@ namespace myxml
element operator""_elem(const char *, std::size_t);
}

class element : public printable
class element : public printable, public interface
{

friend element literals::operator""_elem(const char *, std::size_t);
Expand All @@ -44,40 +72,31 @@ namespace myxml
std::string &operator[](const std::string &);
std::string_view name();

/* Query */
element first_elem();
element first_elem(std::string_view);
text first_text();
cdata first_cdata();

/* Manipulate */
template <typename T, typename SFINAE = std::enable_if_t<std::is_base_of_v<interface, T>>>
void push_back(T child)
{
_impl->push_back(child.impl());
}

template <typename T, typename SFINAE = std::enable_if_t<std::is_base_of_v<interface, T>>>
void push_front(T child)
{
_impl->push_front(child.impl());
}

/* Implement printable */
virtual void print(std::ostream &) const override;
virtual void entity_encoding(bool) override;
virtual void platform_specific_newline(bool) override;
};

struct element_impl : public composite_node // public std::enable_shared_from_this<Element>, public Node
{
public:
std::string _name;
std::map<std::string, std::string, std::less<>> _attributes;

/* Set initializer as private to avoid using Element without share_ptr*/

virtual ~element_impl() = default;
explicit element_impl(std::string_view name);
element_impl() = default;
/* Builder */
// Wraps creating shared_ptr
static std::shared_ptr<element_impl> _new(std::string_view name);
static std::shared_ptr<element_impl> _new();
static std::shared_ptr<element_impl> parse(std::string_view buf);
static std::shared_ptr<element_impl> load(std::string_view path);

/* Manipulate */
void extend_attributes(std::map<std::string, std::string>);
std::string &operator[](const std::string &);

/* Implement Exportable */
virtual void print(std::ostream &) const override;
/* Implement interface*/
virtual std::shared_ptr<node> impl() { return _impl; }
};
}
14 changes: 14 additions & 0 deletions include/myxml/interface.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once
#include <memory>
#include "myxml/node.hpp"

namespace myxml
{
// contains an _impl
// e.g. element, text, cdata
class interface
{
public:
virtual std::shared_ptr<node> impl() = 0;
};
}
22 changes: 0 additions & 22 deletions src/element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,28 +104,6 @@ namespace myxml
return this->_attributes[key];
}

// std::string element_impl::ExportRaw() const
// {

// std::string builder = "<" + std::string(this->name);
// for (const auto &[key, value] : this->attributes)
// {
// builder += "" + key + "=\"" + value + "\"";
// }
// if (this->FirstChild() == nullptr)
// {
// builder += " />";
// return builder;
// }
// builder += ">";
// for (auto node = this->FirstChild(); node != nullptr; node = node->NextSibiling())
// {
// builder += node->ExportRaw();
// }
// builder += "</" + std::string(this->name) + ">";
// return builder;
// }

void element_impl::print(std::ostream &os) const
{
os << "<" << this->_name;
Expand Down
32 changes: 31 additions & 1 deletion tests/element_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,37 @@ TEST_CASE("Element Impl", "[element]")
}
}

TEST_CASE("Custom String Literal", "[Element]")
TEST_CASE("Element Interface", "[element]")
{
using namespace myxml;
using namespace myxml::literals;

element root("root");
element child("child");

SECTION("element::name")
{
REQUIRE(root.name() == "root");
}

SECTION("insertion")
{

root.push_back(child);
REQUIRE(root.first_elem().name() == "child");
element next("next");
root.push_front(next);
REQUIRE(root.first_elem().name() == "next");
}

SECTION("query by name")
{
root.push_back(child);
REQUIRE(root.first_elem("child").name() == "child");
}
}

TEST_CASE("Custom String Literal", "[element]")
{
using namespace myxml::literals;
auto elem = "<root></root>"_elem;
Expand Down

0 comments on commit 17020e2

Please sign in to comment.