aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/cru/ui/mapper/Mapper.h39
1 files changed, 32 insertions, 7 deletions
diff --git a/include/cru/ui/mapper/Mapper.h b/include/cru/ui/mapper/Mapper.h
index 68ad2ab0..e9e7b851 100644
--- a/include/cru/ui/mapper/Mapper.h
+++ b/include/cru/ui/mapper/Mapper.h
@@ -6,7 +6,7 @@
#include <cru/base/xml/XmlNode.h>
#include <memory>
-#include <type_traits>
+#include <optional>
#include <typeindex>
namespace cru::ui::mapper {
@@ -35,12 +35,9 @@ class CRU_UI_API MapperBase : public Object {
template <typename T>
class CRU_UI_API BasicMapper : public MapperBase {
public:
- static_assert(std::is_default_constructible_v<T>,
- "T must be default constructible.");
-
BasicMapper() : MapperBase(typeid(T)) {}
- virtual T MapFromString(std::string str) {
+ T MapFromString(std::string str) {
if (!SupportMapFromString()) {
throw Exception("This mapper does not support map from string.");
}
@@ -61,8 +58,36 @@ class CRU_UI_API BasicMapper : public MapperBase {
}
protected:
- virtual T DoMapFromString(std::string str) { return {}; }
- virtual T DoMapFromXml(xml::XmlElementNode* node) { return {}; }
+ virtual T DoMapFromString(std::string str) { NotImplemented(); }
+ virtual T DoMapFromXml(xml::XmlElementNode* node) { NotImplemented(); }
+
+ T MapFromXmlAsStringValue(xml::XmlElementNode* node,
+ std::optional<T> default_value = std::nullopt) {
+ std::optional<T>& value = default_value;
+
+ auto value_attr = node->GetOptionalAttributeValueCaseInsensitive("value");
+ if (value_attr) {
+ value = DoMapFromString(*value_attr);
+ }
+
+ for (auto child : node->GetChildren()) {
+ if (child->IsElementNode()) {
+ throw MapException("XML node can't contain element child.");
+ } else if (auto c = child->AsText()) {
+ auto text = c->GetText();
+ if (!text.empty() && value.has_value()) {
+ throw MapException("XML node has multiple values specified.");
+ }
+ value = DoMapFromString(text);
+ }
+ }
+
+ if (!value.has_value()) {
+ throw MapException("XML node has no value specified.");
+ }
+
+ return *value;
+ }
};
template <typename T>