-
Notifications
You must be signed in to change notification settings - Fork 134
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
Conversation
There was a problem hiding this 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 ofstd::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 forNamedTuple
,rfl::Tuple
, andstd::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
-
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. ↩
There was a problem hiding this 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.
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; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this 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.
tests/cbor/test_integers.cpp
Outdated
// 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 |
There was a problem hiding this comment.
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:
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF | |
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | |
0xFF |
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(); | ||
} |
There was a problem hiding this comment.
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:
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.
There was a problem hiding this comment.
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 therfl::Rename<Type>
member types... That would be unfortunate.
Yep, exactly
There was a problem hiding this comment.
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.
Signed-off-by: David Corbeil <[email protected]>
@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. |
@dcorbeil thank you for your contribution! @bryceschober , thanks for reviewing it! |
@liuzicheng1987 My pleasure. Thanks for the great library! |
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.