Skip to content

Commit 76fada8

Browse files
FEAT: extend functional of ConfigNodeExpected & ConfigNodeWithPresetExpected (#514)
close #507 --------- Co-authored-by: Павел Ральников <112890673+PaulRalnikov@users.noreply.github.com>
1 parent 3741ad3 commit 76fada8

11 files changed

Lines changed: 290 additions & 155 deletions
Lines changed: 2 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,4 @@
11
#pragma once
2-
#include <yaml-cpp/yaml.h>
32

4-
#include <filesystem>
5-
#include <iostream>
6-
#include <optional>
7-
#include <type_traits>
8-
9-
#include "utils/str_expected.hpp"
10-
11-
namespace sim {
12-
13-
class ConfigNode;
14-
15-
using ConfigNodeExpected = utils::StrExpected<ConfigNode>;
16-
17-
class ConfigNode {
18-
public:
19-
explicit ConfigNode(YAML::Node a_node = YAML::Node(YAML::NodeType::Null),
20-
std::optional<std::string> a_name = std::nullopt);
21-
22-
// Some functional over yaml-cpp
23-
24-
[[nodiscard]] const YAML::Node& get_node() const noexcept;
25-
26-
[[nodiscard]] const std::optional<std::string>& get_name() const noexcept;
27-
28-
[[nodiscard]] const std::string& get_name_or_throw() const;
29-
30-
[[nodiscard]] std::runtime_error create_parsing_error(
31-
std::string_view error) const;
32-
33-
friend std::ostream& operator<<(std::ostream& out, const ConfigNode& node);
34-
35-
std::string to_string() const;
36-
37-
// yaml-cpp functional
38-
39-
[[nodiscard]] YAML::NodeType::value Type() const;
40-
[[nodiscard]] bool IsNull() const noexcept;
41-
[[nodiscard]] bool IsScalar() const noexcept;
42-
[[nodiscard]] bool IsSequence() const noexcept;
43-
[[nodiscard]] bool IsMap() const noexcept;
44-
45-
// access
46-
template <typename T>
47-
[[nodiscard]] utils::StrExpected<T> as() const noexcept {
48-
try {
49-
return m_node.as<T>();
50-
} catch (const std::exception& e) {
51-
return std::unexpected(e.what());
52-
} catch (...) {
53-
return std::unexpected(
54-
"Undefined exception while calling `YAML::Node::as`");
55-
}
56-
}
57-
58-
template <typename T>
59-
T as_or_throw() const {
60-
return as<T>().value_or_throw();
61-
}
62-
63-
[[nodiscard]] const std::string& Tag() const noexcept;
64-
65-
[[nodiscard]] std::size_t size() const noexcept;
66-
67-
class Iterator {
68-
public:
69-
Iterator(YAML::const_iterator a_it);
70-
71-
Iterator& operator++();
72-
73-
Iterator operator++(int);
74-
75-
bool operator==(const Iterator& rhs) const;
76-
77-
bool operator!=(const Iterator& rhs) const;
78-
79-
ConfigNode operator*() const;
80-
81-
private:
82-
// Invariant: m_stacktrace_node is not null
83-
YAML::const_iterator m_iterator;
84-
};
85-
86-
Iterator begin() const;
87-
Iterator end() const;
88-
89-
// indexing
90-
ConfigNodeExpected operator[](std::string_view key) const;
91-
92-
private:
93-
// Always correct
94-
const YAML::Node m_node;
95-
96-
const std::optional<std::string> m_name;
97-
};
98-
99-
ConfigNode load_file(std::filesystem::path path);
100-
101-
} // namespace sim
3+
#include "./config_node_impl.hpp"
4+
#include "./config_node_expected.hpp"
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include "config_node.hpp"
2+
3+
namespace sim{
4+
5+
ConfigNodeExpected::ConfigNodeExpected(utils::StrExpected<ConfigNode> a_node): utils::StrExpected<ConfigNode>(std::move(a_node)){}
6+
7+
[[nodiscard]] utils::StrExpected<std::string> ConfigNodeExpected::get_name() const{
8+
if (!this->has_value()){
9+
return std::unexpected(this->error());
10+
}
11+
const ConfigNode& node = this->value();
12+
const std::optional<std::string>& opt_name = node.get_name();
13+
if (opt_name){
14+
return utils::StrExpected<std::string>(opt_name.value());
15+
} else{
16+
std::stringstream ss;
17+
ss << "Node " << node << " does not have name";
18+
return std::unexpected(ss.str());
19+
}
20+
}
21+
22+
[[nodiscard]] ConfigNodeExpected ConfigNodeExpected::operator[] (std::string_view key) const{
23+
if (!this->has_value()){
24+
return *this;
25+
}
26+
return this->value()[key];
27+
}
28+
29+
} // namespace sim
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#pragma once
2+
3+
#include "utils/str_expected.hpp"
4+
5+
namespace sim {
6+
7+
class ConfigNode;
8+
9+
class ConfigNodeExpected : public utils::StrExpected<ConfigNode> {
10+
public:
11+
using utils::StrExpected<ConfigNode>::StrExpected;
12+
13+
ConfigNodeExpected(utils::StrExpected<ConfigNode> a_node);
14+
15+
template <typename T>
16+
[[nodiscard]] utils::StrExpected<T> as() const noexcept {
17+
if (!this->has_value()) {
18+
return std::unexpected(this->error());
19+
}
20+
return utils::StrExpected<T>(this->value().template as<T>());
21+
}
22+
23+
[[nodiscard]] utils::StrExpected<std::string> get_name() const;
24+
25+
[[nodiscard]] ConfigNodeExpected operator[](std::string_view key) const;
26+
};
27+
28+
} // namespace sim

source/parser/config_reader/config_node.cpp renamed to source/parser/config_reader/config_node_impl.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ ConfigNode::Iterator ConfigNode::begin() const {
122122

123123
ConfigNode::Iterator ConfigNode::end() const { return Iterator(m_node.end()); }
124124

125-
utils::StrExpected<ConfigNode> ConfigNode::operator[](
125+
ConfigNodeExpected ConfigNode::operator[](
126126
std::string_view key) const {
127127
const YAML::Node child_node = m_node[key];
128128
if (!child_node) {
@@ -133,9 +133,9 @@ utils::StrExpected<ConfigNode> ConfigNode::operator[](
133133
}
134134
if (child_node.IsNull()) {
135135
// if node is null, its name should be empty
136-
return ConfigNode(std::move(child_node), std::nullopt);
136+
return ConfigNodeExpected(ConfigNode(std::move(child_node), std::nullopt));
137137
}
138-
return ConfigNode(std::move(child_node), std::string(key));
138+
return ConfigNodeExpected(ConfigNode(std::move(child_node), std::string(key)));
139139
};
140140

141141
ConfigNode load_file(std::filesystem::path path) {
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#pragma once
2+
#include <yaml-cpp/yaml.h>
3+
4+
#include <filesystem>
5+
#include <iostream>
6+
#include <optional>
7+
#include <type_traits>
8+
9+
#include "utils/str_expected.hpp"
10+
11+
namespace sim {
12+
13+
class ConfigNodeExpected;
14+
15+
class ConfigNode {
16+
public:
17+
explicit ConfigNode(YAML::Node a_node = YAML::Node(YAML::NodeType::Null),
18+
std::optional<std::string> a_name = std::nullopt);
19+
20+
// Some functional over yaml-cpp
21+
22+
[[nodiscard]] const YAML::Node& get_node() const noexcept;
23+
24+
[[nodiscard]] const std::optional<std::string>& get_name() const noexcept;
25+
26+
[[nodiscard]] const std::string& get_name_or_throw() const;
27+
28+
[[nodiscard]] std::runtime_error create_parsing_error(
29+
std::string_view error) const;
30+
31+
friend std::ostream& operator<<(std::ostream& out, const ConfigNode& node);
32+
33+
std::string to_string() const;
34+
35+
// yaml-cpp functional
36+
37+
[[nodiscard]] YAML::NodeType::value Type() const;
38+
[[nodiscard]] bool IsNull() const noexcept;
39+
[[nodiscard]] bool IsScalar() const noexcept;
40+
[[nodiscard]] bool IsSequence() const noexcept;
41+
[[nodiscard]] bool IsMap() const noexcept;
42+
43+
// access
44+
template <typename T>
45+
[[nodiscard]] utils::StrExpected<T> as() const noexcept {
46+
try {
47+
return m_node.as<T>();
48+
} catch (const std::exception& e) {
49+
return std::unexpected(e.what());
50+
} catch (...) {
51+
return std::unexpected(
52+
"Undefined exception while calling `YAML::Node::as`");
53+
}
54+
}
55+
56+
template <typename T>
57+
T as_or_throw() const {
58+
return as<T>().value_or_throw();
59+
}
60+
61+
[[nodiscard]] const std::string& Tag() const noexcept;
62+
63+
[[nodiscard]] std::size_t size() const noexcept;
64+
65+
class Iterator {
66+
public:
67+
Iterator(YAML::const_iterator a_it);
68+
69+
Iterator& operator++();
70+
71+
Iterator operator++(int);
72+
73+
bool operator==(const Iterator& rhs) const;
74+
75+
bool operator!=(const Iterator& rhs) const;
76+
77+
ConfigNode operator*() const;
78+
79+
private:
80+
// Invariant: m_stacktrace_node is not null
81+
YAML::const_iterator m_iterator;
82+
};
83+
84+
Iterator begin() const;
85+
Iterator end() const;
86+
87+
// indexing
88+
ConfigNodeExpected operator[](std::string_view key) const;
89+
90+
private:
91+
// Always correct
92+
const YAML::Node m_node;
93+
94+
const std::optional<std::string> m_name;
95+
};
96+
97+
ConfigNode load_file(std::filesystem::path path);
98+
99+
} // namespace sim
Lines changed: 2 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,4 @@
11
#pragma once
22

3-
#include "./config_node.hpp"
4-
5-
namespace sim {
6-
7-
class ConfigNodeWithPreset;
8-
9-
using ConfigNodeWithPresetExpected = utils::StrExpected<ConfigNodeWithPreset>;
10-
11-
// Config node that supports preset inheritance.
12-
class ConfigNodeWithPreset {
13-
public:
14-
explicit ConfigNodeWithPreset(
15-
ConfigNode a_node,
16-
std::optional<ConfigNode> a_presets_node = std::nullopt,
17-
std::optional<ConfigNode> a_preset = std::nullopt);
18-
19-
ConfigNodeWithPresetExpected operator[](std::string_view key) const;
20-
21-
// Returns the base config node.
22-
const ConfigNode& get_node() const noexcept;
23-
24-
const std::optional<ConfigNode> get_presets_node() const noexcept;
25-
26-
// Converts m_node to type T. Probably this method will return message about
27-
// error
28-
template <typename T>
29-
[[nodiscard]] utils::StrExpected<T> as() const noexcept {
30-
return m_node.as<T>();
31-
}
32-
33-
template <typename T>
34-
T as_or_throw() const {
35-
return as<T>().value_or_throw();
36-
}
37-
38-
[[nodiscard]] const std::string& get_name_or_throw() const;
39-
40-
[[nodiscard]] std::runtime_error create_parsing_error(
41-
std::string_view error) const;
42-
43-
private:
44-
// m_node contains information about config node and probably preset name
45-
// m_preset - preset node which that is used to supplement fields of m_node
46-
// m_presets_node - node it which preset node should be searched (id it
47-
// needs)
48-
const ConfigNode m_node;
49-
const std::optional<ConfigNode> m_presets_node;
50-
mutable std::optional<ConfigNode> m_preset;
51-
};
52-
53-
} // namespace sim
3+
#include "config_node_with_preset_impl.hpp"
4+
#include "config_node_with_preset_expected.hpp"
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include "config_node_with_preset.hpp"
2+
3+
namespace sim {
4+
5+
ConfigNodeWithPresetExpected::ConfigNodeWithPresetExpected(
6+
ConfigNodeWithPreset a_node)
7+
: utils::StrExpected<ConfigNodeWithPreset>(std::move(a_node)) {}
8+
9+
[[nodiscard]] utils::StrExpected<std::string>
10+
ConfigNodeWithPresetExpected::get_name() const {
11+
if (!this->has_value()) {
12+
return std::unexpected(this->error());
13+
}
14+
const ConfigNodeWithPreset& node = this->value();
15+
const std::optional<std::string>& opt_name = node.get_name();
16+
if (opt_name) {
17+
return utils::StrExpected<std::string>(opt_name.value());
18+
} else {
19+
std::stringstream ss;
20+
ss << "Node " << node << " doesn't have name";
21+
return std::unexpected(ss.str());
22+
}
23+
}
24+
25+
[[nodiscard]] ConfigNodeWithPresetExpected ConfigNodeWithPresetExpected::operator[](std::string_view key) const {
26+
if (!this->has_value()) {
27+
return *this;
28+
}
29+
return this->value()[key];
30+
}
31+
32+
} // namespace sim

0 commit comments

Comments
 (0)