-
Notifications
You must be signed in to change notification settings - Fork 4
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
Add json{::partial,}::scan() in the likes of the scanf() API #43
base: develop
Are you sure you want to change the base?
Conversation
There is a lot to comprehend here, so I will just make some random comments. Rather than having direct support for |
There are two sides of this comment. One is interface. Should we keep support for these types at all? Second is implementation. Should we use For the implementation case, going through For the interface case, I believe basic type validation is a strong reason behind a Is the current level of “formatted scan” (i.e. embedded type checking) desired? Should we decrease the performed level of type checking and throw some of this work on user's hand? Should we go the other way and increase type checking? Increasing embedded type checking could mean to add an ADL-like interface in the likes of Another step in this direction would be to add support for |
So, as an example of what I meant by this... the other day I had to implement code to consume permissions and I used {
"group": {
// ...
}
"action1-perm": "rx",
// ...
} or an object like this: {
"group": {
"action1-perm": "rx",
// ...
}
// ...
} User-level permissions take precedence over group permissions. Therefore, the code would be like: if (trial::dynamic::key::find(result, "action1-perm") != result.key_end()) {
// ...
} else {
auto group_it = trial::dynamic::key::find(result, "group");
if (group_it == result.key_end()) {
// assign default permission
} else {
// ...
}
} Rather convoluted code. I'd rather write something like: std::optional<std::string> user;
std::optional<std::string> group;
json::scan(input, "{ group: { action1-perm: ? }, action1-perm: ? }"_s, group, user);
if (user) {
// ...
} else if (group) {
// ...
} else {
// assign default permission
} Way cleaner code. |
I do not question the utility of My main concerns are
As an example, serialization addresses both these concerns. |
I'll open a smaller PR that integrates serialization support and Boost.Hana reflection. When we sort this new PR out, I'll be back to refactor this branch. |
I changed my mind again (partially). I'll drop my new thoughts on #26. |
Implementation-wise, everything is done. I do intend to extend the interface, but doing so is an addition (one of the additions is related to this Boost.Hana's issue), not a change. Therefore I consider the PR done as is.
However I'd like to leave it open for a few months while we discuss it.
@xvjau did suggest me to add a
scanf()
like the following:That's one of the intended additions. Before I spend more time extending the API, I'd like to have the basic interface settled as it'll mean less work for me.
What already works (check the test suite for examples):
reader.value<T>()
).boost::optional<T>
.string_view
(the literal is feeded).vector<T>
..std::vector<bool>
doesn't work because it needs special handling (I think I can add it thou if desired)dynamic::variable
.boost::variant<Ts...>
(ifboost::none_t
is inTs...
, then the argument is treated as optional).dynamic::variable
,boost::optional<T>
, orboost::variant<..., boost::none_t, ...>
. I considered making a syntax for optional callbacks, but it added confusion to the interface and the user can just do this with wildcard match on the desired level.partial::scan()
function to parse subtrees).The interface might look a little verbose with all that
boost::hana::map
creation, but this interface actually works great to be further used in another metaprogram. Therefore I consider it desirable and part of the basic API. User might just want to usejson::scan()
implementation while it exposes a completely different interface. In fact, I intend to implement @xvjau's suggestion mentioned above in terms of this very API.As before, I no longer see a need for #26 as I initially proposed. Fields can come in any order and consuming one field means the next desired field might already have been consumed. OTOH, that's not a problem for the
scan()
API as it can freely combine multiple search requests (and there's even wildcard match for other values).So... thoughts?