Skip to content

Remove vast::json class #1343

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

ngrodzitski
Copy link
Contributor

📔 Description

Remove vast::json from vast.

📝 Checklist

  • All user-facing changes have changelog entries.
  • The changes are reflected on docs.tenzir.com/vast, if necessary.
  • The PR description contains instructions for the reviewer, if necessary.

🎯 Review Instructions

@ngrodzitski ngrodzitski changed the title Dev remove old json Remove vast::json class Feb 4, 2021
return real_type{};
if (x < 0)
return integer_type{};
type deduce(simdjson::dom::element e) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is a ambiguity in how to interpret a given json values as types.
This is example from integration test (which should fail currently):

{ "a": null, "b": true, "c": false, "d": 0, "e": -0, "f": -42, "g": 4.2, "h": 42.0, "i": 42}
-type json = record{a: none, b: bool, c: bool, d: real, e: real, f: int, g: real, h: count, i: count}
+type json = record{a: none, b: bool, c: bool, d: int, e: int, f: int, g: real, h: real, i: int}

Copy link
Member

Choose a reason for hiding this comment

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

That's just the nature of vast::data being more powerful than JSON. I'll discuss with the team which conversions are preferred.

Copy link
Member

Choose a reason for hiding this comment

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

After looking at the source code some more, I think the way you implemented this is absolutely correct. Please update the integration test accordingly.

@@ -54,13 +56,37 @@ struct data_printer : printer<data_printer> {
}
};

using json_data_printer = json_printer<policy::tree, 2>;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't delete vast/concept/printable/vast/json.hpp header and reuse its printer as a second option for vast::data printer:

auto text_str = to_string(data_object); // default to_string(data) rendering
auto json_str = to_string(data_object, print_rendering::json); // explicitly set json rendering

If the idea of such extended to_string(data, rendering) is ok, then json_data_printer can be moved here entirely.

Copy link
Member

Choose a reason for hiding this comment

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

For YAML we use this:

/// Prints data as YAML.
/// @param x The data instance.
/// @returns The YAML representation of *x*, or an error.
caf::expected<std::string> to_yaml(const data& x);

/// Parses YAML into a data.
/// @param str The string containing the YAML content
/// @returns The parsed YAML as data, or an error.
caf::expected<data> from_yaml(std::string_view str);

So I think you can just name the function to_json and have it return a caf::expected<std::string>.


/// Converts data with a type to "zipped" JSON, i.e., the JSON object for
/// records contains the field names from the type corresponding to the given
/// data.
bool convert(const data& x, json& j, const type& t);
// bool convert(const data& x, json& j, const type& t);

caf::error convert(const record& xs, caf::dictionary<caf::config_value>& ys);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Those 3 convert functions are quite asymmetric to many other convert function in vast, which return bool to manifest the result of conversion. while if (convert(x,y)) is test on success for return-bool-based convert functions it is a test on fail for return-caf::error-based convert function.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, they were overlooked in a past refactoring. Generally, convert overloads must return something that is explicitly convertible to bool, but just returning bool is preferred since the errors aren't checked anyways.

@dominiklohmann
Copy link
Member

Thanks for the PR; this will take while for me to go through it, but I will do a first pass sometime today and then we can hopefully merge this early next week to avoid merge conflicts as much as possible.

Copy link
Member

@dominiklohmann dominiklohmann left a comment

Choose a reason for hiding this comment

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

Looking really good so far.

  • Please use to_json over to_string(data, tag_type).
  • There are some leftover integration test file with simdjson in their name.

/// Prints data as JSON.
/// @param x The data instance.
/// @returns The JSON representation of *x*, or an error.
caf::expected<std::string> to_json(const data& x);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thinking of these to_string/to_json/to_yaml family of function and having fmt already in vast I'd like to share a quick observation:

I think the whole engine of printable things can be rebuilt with fmt (thankfully vast printable machinery is very similar to the one in fmt), thus reducing maintenance costs in a long run (a wide community is interested to have FMT a bug-free and performant) and be more 3rd-party friendly (e.g. plugins authors would have a kind of "standard" approach to do printings with vast types). Also it would be more expressive and flexible to have possible rendering formats as options, something like the following:

auto d = vast::data{ make_something()};
auto text = fmt::format("{}", d);
auto json = fmt::format("{j}", d);
auto yaml = fmt::format("{y}", d);

Copy link
Member

Choose a reason for hiding this comment

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

This is great observation. We actually had the very same discussion last week: what's the future of our concepts, in particular Printable, Parseable, Hashable. It's no question that FMT is a major win and probably our best for the implementation of what we call Printable right now.

A while ago, we wanted to have to<yaml>, to<json>, etc. for rendering a type in a specific way. (The to overloads return an expected<T> instead of a T.) But we are moving away from that. Now that json is gone, we're actually going in a different direction.

The underlying question is: what's the most flexible mechanism to print one type in different ways? By treating FMT a first-class library in the code base, your proposal makes a lot of sense. The only thing I wish we had is a symmetric API for parsing. I'm not sure if these are realistic expectations, though.

Copy link
Member

Choose a reason for hiding this comment

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

We've had the discussion before @mavam, and I feel like forcing APIs to be symmetric will just hold us back.

For now, I think to_json is fine, but I agree with @ngrodzitski that a format option for {fmt} would be much more friendly to plugin authors.

ngrodzitski and others added 9 commits February 7, 2021 22:37
Adjust for namespace `vast::format::json` and modify json import integration tests to be based on simdjson.
This is a backup commit which stores a compilable version. Writer test fails and some other tests are temporary disabled.
Co-authored-by: Dominik Lohmann <mail@dominiklohmann.de>
@dominiklohmann
Copy link
Member

I'll merge this into another branch now to do some cleanup and to write a changelog entry and documentation. Thanks for your work on this @ngrodzitski! 🙏

@dominiklohmann dominiklohmann changed the base branch from master to story/ch4981/legacy-json-removal February 8, 2021 13:45
@dominiklohmann dominiklohmann merged commit 74069ba into tenzir:story/ch4981/legacy-json-removal Feb 8, 2021
@dominiklohmann dominiklohmann mentioned this pull request Feb 8, 2021
3 tasks
@mavam mavam added the refactoring Restructuring of existing code label Feb 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
refactoring Restructuring of existing code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants