Skip to content

Commit f2f2f36

Browse files
Added comments to YAML
1 parent 6b82c10 commit f2f2f36

8 files changed

Lines changed: 86 additions & 42 deletions

File tree

include/rfl.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include "rfl/Binary.hpp"
1717
#include "rfl/Box.hpp"
1818
#include "rfl/Bytestring.hpp"
19+
#include "rfl/CamelCaseToSnakeCase.hpp"
20+
#include "rfl/Commented.hpp"
1921
#include "rfl/DefaultIfMissing.hpp"
2022
#include "rfl/DefaultVal.hpp"
2123
#include "rfl/Description.hpp"
@@ -41,7 +43,6 @@
4143
#include "rfl/Skip.hpp"
4244
#include "rfl/SnakeCaseToCamelCase.hpp"
4345
#include "rfl/SnakeCaseToPascalCase.hpp"
44-
#include "rfl/CamelCaseToSnakeCase.hpp"
4546
#include "rfl/TaggedUnion.hpp"
4647
#include "rfl/Timestamp.hpp"
4748
#include "rfl/UnderlyingEnums.hpp"

include/rfl/Commented.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include <type_traits>
77
#include <utility>
88

9+
#include "default.hpp"
10+
911
namespace rfl {
1012

1113
template <class T>

include/rfl/parsing/Parent.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "../always_false.hpp"
88
#include "schemaful/IsSchemafulWriter.hpp"
99
#include "supports_attributes.hpp"
10+
#include "supports_comments.hpp"
1011

1112
namespace rfl::parsing {
1213

@@ -71,6 +72,21 @@ struct Parent {
7172
}
7273
}
7374

75+
/// Adds a comment to the parent element, if supported by the writer.
76+
template <class ParentType>
77+
static void add_comment(const W& _w, std::string_view _comment,
78+
const ParentType& _parent) {
79+
using Type = std::remove_cvref_t<ParentType>;
80+
if constexpr (supports_comments<W>) {
81+
if constexpr (std::is_same<Type, Array>()) {
82+
_w.add_comment_to_array(_comment, _parent.arr_);
83+
84+
} else if constexpr (std::is_same<Type, Object>()) {
85+
_w.add_comment_to_object(_comment, _parent.obj_);
86+
}
87+
}
88+
}
89+
7490
// For schemaful formats only.
7591
template <class ParentType>
7692
static auto add_map(const W& _w, const size_t _size,

include/rfl/parsing/Parser_commented.hpp

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,30 +28,21 @@ struct Parser<R, W, Commented<T>, ProcessorsType> {
2828

2929
static Result<Commented<T>> read(const R& _r,
3030
const InputVarType& _var) noexcept {
31-
if constexpr (supports_comments<R>) {
32-
return Parser<R, W, std::remove_cvref_t<T>, ProcessorsType>::read(_r,
33-
_var)
34-
.transform([&](auto&& _t) {
35-
return Commented<T>(std::move(_t), _r.get_comment(_var));
36-
});
37-
} else {
38-
return Parser<R, W, std::remove_cvref_t<T>, ProcessorsType>::read(_r,
39-
_var)
40-
.transform([](auto&& _t) {
41-
return Commented<T>(std::forward<decltype(_t)>(_t));
42-
});
43-
}
31+
return Parser<R, W, std::remove_cvref_t<T>, ProcessorsType>::read(_r, _var)
32+
.transform([](auto&& _t) {
33+
return Commented<T>(std::forward<decltype(_t)>(_t));
34+
});
4435
}
4536

4637
template <class P>
4738
static void write(const W& _w, const Commented<T>& _c, const P& _parent) {
39+
Parser<R, W, std::remove_cvref_t<T>, ProcessorsType>::write(_w, _c.get(),
40+
_parent);
4841
if constexpr (supports_comments<W>) {
4942
if (_c.comment()) {
50-
_w.add_comment(_parent, *_c.comment());
43+
ParentType::add_comment(_w, *_c.comment(), _parent);
5144
}
5245
}
53-
Parser<R, W, std::remove_cvref_t<T>, ProcessorsType>::write(_w, _c.get(),
54-
_parent);
5546
}
5647

5748
static schema::Type to_schema(

include/rfl/parsing/supports_comments.hpp

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,18 @@
77
#include <string_view>
88

99
#include "../Result.hpp"
10-
#include "IsReader.hpp"
11-
#include "IsWriter.hpp"
1210

1311
namespace rfl::parsing {
1412

15-
/// Determines whether a reader supports comments.
16-
template <class R>
17-
concept reader_supports_comments =
18-
requires(R r, typename R::InputVarType var, std::string_view comment) {
19-
{ r.get_comment(var) } -> std::same_as<std::optional<std::string>>;
20-
};
21-
2213
/// Determines whether a writer supports comments.
2314
template <class W>
24-
concept writer_supports_comments =
25-
requires(W w, Parent<W> parent, std::string_view comment) {
26-
{
27-
w.add_comment(parent, comment)
28-
} -> std::same_as<typename W::OutputVarType>;
29-
};
30-
31-
template <class RorW>
3215
concept supports_comments =
33-
(IsReader<RorW, int> && reader_supports_comments<RorW>) ||
34-
(IsWriter<RorW, int> && writer_supports_comments<RorW>);
16+
requires(W w, typename W::OutputArrayType arr,
17+
typename W::OutputObjectType obj, std::string_view comment) {
18+
{ w.add_comment_to_array(comment, &arr) } -> std::same_as<void>;
19+
20+
{ w.add_comment_to_object(comment, &obj) } -> std::same_as<void>;
21+
};
3522

3623
} // namespace rfl::parsing
3724

include/rfl/yaml/Writer.hpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
#include "../always_false.hpp"
1212
#include "../common.hpp"
1313

14-
namespace rfl {
15-
namespace yaml {
14+
namespace rfl::yaml {
1615

1716
class RFL_API Writer {
1817
public:
@@ -42,11 +41,17 @@ class RFL_API Writer {
4241
}
4342

4443
OutputArrayType add_array_to_array(const size_t _size,
45-
OutputArrayType* _parent) const;
44+
OutputArrayType* /*_parent*/) const;
4645

4746
OutputArrayType add_array_to_object(const std::string_view& _name,
4847
const size_t _size,
49-
OutputObjectType* _parent) const;
48+
OutputObjectType* /*_parent*/) const;
49+
50+
void add_comment_to_array(const std::string_view& _comment,
51+
OutputArrayType* _parent) const;
52+
53+
void add_comment_to_object(const std::string_view& _comment,
54+
OutputObjectType* _parent) const;
5055

5156
OutputObjectType add_object_to_array(const size_t _size,
5257
OutputArrayType* _parent) const;
@@ -122,6 +127,8 @@ class RFL_API Writer {
122127

123128
OutputArrayType new_array() const;
124129

130+
void new_comment(const std::string_view& _comment) const;
131+
125132
OutputObjectType new_object(const std::string_view& _name) const;
126133

127134
OutputObjectType new_object() const;
@@ -130,7 +137,6 @@ class RFL_API Writer {
130137
const Ref<YAML::Emitter> out_;
131138
};
132139

133-
} // namespace yaml
134-
} // namespace rfl
140+
} // namespace rfl::yaml
135141

136142
#endif

src/rfl/yaml/Writer.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ Writer::OutputArrayType Writer::add_array_to_object(
2929
return new_array(_name);
3030
}
3131

32+
void Writer::add_comment_to_array(const std::string_view& _comment,
33+
OutputArrayType*) const {
34+
new_comment(_comment);
35+
}
36+
37+
void Writer::add_comment_to_object(const std::string_view& _comment,
38+
OutputObjectType*) const {
39+
new_comment(_comment);
40+
}
41+
3242
Writer::OutputObjectType Writer::add_object_to_array(
3343
const size_t /*_size*/, OutputArrayType* /*_parent*/) const {
3444
return new_object();
@@ -68,6 +78,10 @@ Writer::OutputArrayType Writer::new_array() const {
6878
return OutputArrayType{};
6979
}
7080

81+
void Writer::new_comment(const std::string_view& _comment) const {
82+
(*out_) << YAML::Comment(std::string(_comment));
83+
}
84+
7185
Writer::OutputObjectType Writer::new_object(
7286
const std::string_view& _name) const {
7387
(*out_) << YAML::Key << std::string(_name) << YAML::Value << YAML::BeginMap;

tests/yaml/test_comment.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <rfl.hpp>
2+
#include <string>
3+
#include <vector>
4+
5+
#include "write_and_read.hpp"
6+
7+
namespace test_comment {
8+
9+
struct Person {
10+
std::string first_name;
11+
std::string last_name;
12+
rfl::Commented<std::string> town;
13+
};
14+
15+
TEST(yaml, test_comment) {
16+
const auto homer = Person{.first_name = "Homer",
17+
.last_name = "Simpson",
18+
.town = rfl::Commented<std::string>(
19+
"Springfield", "The town where Homer lives")};
20+
21+
const auto yaml_str = rfl::yaml::write(homer);
22+
23+
EXPECT_EQ(yaml_str, R"(first_name: Homer
24+
last_name: Simpson
25+
town: Springfield # The town where Homer lives)");
26+
}
27+
} // namespace test_comment

0 commit comments

Comments
 (0)