Skip to content
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

Reduce verbosity during dotted key access. #118

Closed
ben-crowhurst opened this issue Oct 3, 2021 · 8 comments
Closed

Reduce verbosity during dotted key access. #118

ben-crowhurst opened this issue Oct 3, 2021 · 8 comments
Assignees
Labels
feature New feature or enhancement request implemented in v3 Fixes + features which were implemented in v3 release.

Comments

@ben-crowhurst
Copy link

When accessing a property at a known dotted key location. The current API requires splitting the key and iterating over the subscript operator in an attempt to get the value.

return _config["cpu"]["watermark"]["upper"].value_or(default_value);

It would be convenient and less verbose to write:

return _config.find("cpu.watermark.upper");

@ben-crowhurst ben-crowhurst added the feature New feature or enhancement request label Oct 3, 2021
@marzer
Copy link
Owner

marzer commented Oct 7, 2021

Hi, thanks for the suggestion. This indeed would be a good convenience utility to add to the library. I don't really have the time to do non-bugfix work on toml++ at the moment, but fortunately in your case an implementation of this functionality would be pretty easy to stitch together locally in the mean time. The helper function I put together in my response to this issue gets you most of the way there, only needing the string-splitting functionality and it's pretty much exactly what you're after.

@ben-crowhurst
Copy link
Author

Thanks for the reply @marzer. We currently have a workaround in play, was a nice to have down the road kind of suggestion.

@marzer marzer added the v3 label Oct 25, 2021
@marzer marzer added implemented in v3 Fixes + features which were implemented in v3 release. and removed v3 labels Jan 7, 2022
@marzer
Copy link
Owner

marzer commented Jan 7, 2022

@ben-crowhurst This is now implemented on the v3 branch, as:

  • free function toml::at_path(node&, std::string_view)
  • member function toml::node::at_path(std::string_view)
  • member function toml::node_view::at_path(std::string_view)

Each returns a node_view. They'll do proper "TOML path" resolving, including array indexing:

[foo]
bar = [ 0, 1, 2, [ 3 ], { kek = 4 } ]
std::cout << toml::at_path(config, "foo.bar[2]") << "\n";
std::cout << toml::at_path(config, "foo.bar[3][0]") << "\n";
std::cout << toml::at_path(config, "foo.bar[4].kek") << "\n";

will print

2
3
4

I didn't call it find() since toml::table::find() already existed with the same semantics as std::map::find(). Don't know if I love the name at_path() either, but naming things is hard ¯\_(ツ)_/¯

The full list of changes in the v3 branch can be found here.

@marzer marzer closed this as completed in 3f4a540 Jan 11, 2022
@bencrowhurst
Copy link

Fantastic @marzer! I'd hoped to get to this myself, but finding time is always a constraining factor.

Thank you for this feature and the project 👍

@wakely
Copy link

wakely commented Mar 4, 2022

The at_path() methods are really a nice addition.

Is there a way to go the other way around? In other words, from a node_view, extract the path that got us to it? Essentially something equivalent to:

auto nv = table.at_path("here.is.my.path");
auto path = nv.path_to_node();  //returns "here.is.my.path"

@marzer
Copy link
Owner

marzer commented Mar 4, 2022

@wakely Currently, no, there's no way to go back in the other direction. Doing so would require that nodes + node views keep track of their parents, which isn't the case in the current implementation.

I might consider adding this at some stage, but since it would necessitate adding additional state to nodes and node views, it will be an ABI break, so it won't be until the next time I do a major release.

If you're always using at_path() to get the node views in the first place you could implement a poor man's version of this yourself by wrapping at_path() in a function that returns a node view + path pair, e.g.:

template <typename Node>
struct node_view_path_pair
{
	toml::node_view<Node> node_view;
	std::string path; // or std::string_view if the at_path() inputs are always string literals
};

node_view_path_pair<toml::node> at_path_retraceable(node& root, std::string_view path)
{
	auto result = toml::at_path(root, path);
	if (result)
		return { result, path };
	return {};
}

@wakely
Copy link

wakely commented Mar 4, 2022

@marzer thanks for the feedback and suggestion. The use case is really more for pathfinding after having arrived at a node by some other arcane table traversal voodoo. I could wrap everything info methods that "accumulate" path, I guess, but this would have been crisp and clean.

@marzer
Copy link
Owner

marzer commented Mar 4, 2022

I could wrap everything info methods that "accumulate" path, I guess, but this would have been crisp and clean.

Yup, certainly would be cleaner as member functions. Until then there's a helper function example in the discussion of this issue that might help with the accumulation implementation. It's not exactly what you want but would be easy to modify to suit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or enhancement request implemented in v3 Fixes + features which were implemented in v3 release.
Projects
None yet
Development

No branches or pull requests

4 participants