Thanks to visit codestin.com
Credit goes to github.com

Skip to content

cbor supports std::optional; fixes #135 #462

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 16, 2025

Conversation

dcorbeil
Copy link
Contributor

I went for the option to generate indeterminate length maps. This allows to not require knowing the size of a struct (for example) in advance for the top level size of the cbor maps or even nested maps.

Eventually adding an option to control whether the generated cbor is determinate or indeterminate map lengths.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @dcorbeil, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the CBOR serialization capabilities by adding native support for std::optional types. This is achieved by transitioning to indeterminate length CBOR maps, which removes the prior constraint of knowing object sizes upfront. The changes also include improvements to error messages and a refactoring of the CBOR parser, making the system more robust and easier to use for flexible data structures.

Highlights

  • std::optional Support: This pull request introduces comprehensive support for std::optional types within the CBOR serialization and deserialization process. This allows for more flexible data structures where fields may or may not be present.
  • Indeterminate Length CBOR Maps: The CBOR writer has been updated to generate indeterminate length maps (using the 0xBF major type) instead of fixed-size maps. This change simplifies the handling of optional fields, as the total number of key-value pairs in a map no longer needs to be known in advance, aligning with the flexible nature of std::optional.
  • Improved Error Reporting: The error messages for CBOR parsing failures have been enhanced to provide more specific details, such as identifying missing fields, which aids in debugging and understanding parsing issues.
  • CBOR Parser Refactoring: The include/rfl/cbor/Parser.hpp file has been refactored by removing specific template specializations for NamedTuple, rfl::Tuple, and std::tuple, streamlining the CBOR parsing infrastructure.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for std::optional in CBOR serialization by switching to indeterminate-length maps. The changes are well-implemented, and the new tests are comprehensive. There is a suggestion regarding code duplication in the new test files.

Comment on lines +10 to +14
struct Person {
rfl::Rename<"firstName", std::string> first_name;
rfl::Rename<"lastName", std::string> last_name = "Simpson";
rfl::Rename<"children", std::optional<std::vector<Person>>> children;
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The Person struct is also defined in tests/cbor/test_optional_fields.cpp. Consider moving this common struct definition to a shared header file to avoid code duplication and improve maintainability.

Copy link
Contributor

@bryceschober bryceschober left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, with the exception of some small suggestions.

// See: https://www.rfc-editor.org/rfc/rfc8949.html#section-appendix.b
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Line-break the indefinite length stop code, so it looks more separate from the data, as in your other example:

Suggested change
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF

Comment on lines +16 to +20
bool operator==(const Person& other) const {
return first_name.get() == other.first_name.get() &&
last_name.get() == other.last_name.get() &&
children.get() == other.children.get();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Use the C++20 default comparison operator:

Suggested change
bool operator==(const Person& other) const {
return first_name.get() == other.first_name.get() &&
last_name.get() == other.last_name.get() &&
children.get() == other.children.get();
}
bool operator==(const Person& other) const = default;

Although now that I'm thinking about it, perhaps this was done because the default comparison operator is not able to use the const Type& operator()() that is defined for the rfl::Rename<Type> member types... That would be unfortunate.

If that's the case, it would be helpful to briefly document that fact here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although now that I'm thinking about it, perhaps this was done because the default comparison operator is not able to use the const Type& operator()() that is defined for the rfl::Rename<Type> member types... That would be unfortunate.

Yep, exactly

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@liuzicheng1987 @dcorbeil I wonder if there is some comparison operator that rfl::Rename<Type> could implement to "pass through" default comparison operator support to its type.

@liuzicheng1987
Copy link
Contributor

@dcorbeil thanks for the PR. Sorry it took me a couple of days to get to it, I was a bit busy. I will take a closer look tonight.

@liuzicheng1987
Copy link
Contributor

@dcorbeil thank you for your contribution! @bryceschober , thanks for reviewing it!

@liuzicheng1987 liuzicheng1987 merged commit ee1da7b into getml:main Jul 16, 2025
13 of 14 checks passed
@dcorbeil dcorbeil deleted the cbor_optional branch July 17, 2025 13:59
@dcorbeil
Copy link
Contributor Author

@liuzicheng1987 My pleasure. Thanks for the great library!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants