Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,7 @@ In addition, it supports the following custom containers:
- `rfl::Binary`: Used to express numbers in binary format.
- `rfl::Box`: Similar to `std::unique_ptr`, but (almost) guaranteed to never be null.
- `rfl::Bytestring`: An alias for `std::vector<std::byte>`. Supported by Avro, BSON, Cap'n Proto, CBOR, flexbuffers, msgpack and UBJSON.
- `rfl::Commented`: Allows you to add comments to fields (supported by YAML and XML).
- `rfl::Generic`: A catch-all type that can represent (almost) anything.
- `rfl::Hex`: Used to express numbers in hex format.
- `rfl::Literal`: An explicitly enumerated string.
Expand Down
81 changes: 81 additions & 0 deletions docs/commented.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# `rfl::Commented`

The `rfl::Commented<T>` wrapper allows you to add comments to fields in your structs. These comments are then serialized in formats that support them, such as YAML and XML.

Note that `rfl::Commented` is currently unsupported by formats that do not have a standard way of representing comments, such as JSON. Also note that comments are **write-only**: they are ignored during deserialization.

## Example (YAML)

In YAML, the comments are added as line comments (`#`):

```cpp
struct Person {
std::string first_name;
std::string last_name;
rfl::Commented<std::string> town;
};

const auto homer = Person{.first_name = "Homer",
.last_name = "Simpson",
.town = rfl::Commented<std::string>(
"Springfield", "The town where Homer lives")};

const auto yaml_str = rfl::yaml::write(homer);
```

This will result in the following YAML:

```yaml
first_name: Homer
last_name: Simpson
town: Springfield # The town where Homer lives
```

## Example (XML)

In XML, the comments are added as `<!-- comment -->` blocks after the field:

```cpp
struct Person {
std::string first_name;
std::string last_name;
rfl::Commented<std::string> town;
};

const auto homer = Person{.first_name = "Homer",
.last_name = "Simpson",
.town = rfl::Commented<std::string>(
"Springfield", "The town where Homer lives")};

const auto xml_str = rfl::xml::write(homer);
```

This will result in the following XML:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Person>
<first_name>Homer</first_name>
<last_name>Simpson</last_name>
<town>Springfield</town>
<!--The town where Homer lives-->
</Person>
```

## API convenience

`rfl::Commented` provides several ways to access and modify the underlying value and the comment:

- `.get()`, `.value()`, `operator()()` — access the underlying value (const and non-const overloads).
- `.comment()` — returns an `std::optional<std::string>` containing the comment.
- `.add_comment(std::string)` — sets or updates the comment.
- `.set(...)`, `operator=(...)` — assign the underlying value.

Example:

```cpp
Person p;
p.town = "Springfield";
p.town.add_comment("The town where Homer lives");
std::string s = p.town.value();
```
1 change: 1 addition & 0 deletions mkdocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ nav:
- rfl::Box and rfl::Ref: rfl_ref.md
- rfl::Timestamp: timestamps.md
- rfl::Skip: rfl_skip.md
- rfl::Commented: commented.md
- rfl::Result: result.md
- Standard containers: standard_containers.md
- C arrays and inheritance: c_arrays_and_inheritance.md
Expand Down
Loading