-
Notifications
You must be signed in to change notification settings - Fork 273
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
json_selection: fix pretty print duplicate $ #5248
Conversation
CI performance tests
|
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.
Please add more tests that actually exercise this code, as well as other aspects of JSONSelection
syntax. Making the one-line change I suggested does not give me any reassurance the rest of the pretty_print
code is correct, or will remain correct in the future.
3c03b53
to
4b6f484
Compare
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.
Thanks for going the extra mile and moving this trait into its own file, in addition to adding all the tests.
I realize I may have already asked for more of your time than you wanted to spend on this, so if you don't have time to try the Result
simplification I mentioned below, I can get to it when I put up my next PR (which has a use for pretty_print
).
/// Display implementation, which might be more useful for snapshots. | ||
pub trait PrettyPrintable { | ||
/// Pretty print the struct | ||
fn pretty_print(&self) -> Result<String, std::fmt::Error> { |
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.
It looks like the only reason pretty_print
needs to return a Result<String, std::fmt::Error>
instead of String
is because it uses the write!
and writeln!
macros, which I suppose can be fallible.
Since this code is only building up a string, I suspect we could use result.push_str
(more than once in some cases) instead of the write[ln]!
macros, and then the pretty_print
signature could be just fn pretty_print(&self) -> String
.
Was there another reason for returning Result
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.
The main motivation was the fact that using write!
allows for directly using formatted strings vs having to use the nested .push_str(&format!(...))
. If you get the chance to simplify this in your next PR, please do!
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.
you should definitely use write!()
over push_str(&format!())
. If the output is known to be a String
, write!()
is infallible, so you can do write!().unwrap()
or even _ = write!()
to silence the warning.
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.
That said, even better would be if the pretty printing trait used an f: &mut fmt::Formatter
parameter for output, to avoid allocating many intermediate strings. That is not something that needs to be done in this PR of course :) See the query_plan::display
module for inspiration.
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.
To clarify, I wasn't suggesting push_str(&format!(...))
but just push_str(&str)
(and sometimes push(char)
), as in the following diff:
@@ -378,26 +389,29 @@ impl PathSelection {
}
}
- pub fn pretty_print_with_indentation(&self, indentation: usize) -> Result<String, std::fmt::Error> {
+ pub fn pretty_print_with_indentation(&self, indentation: usize) -> String {
let mut result = String::new();
match self {
PathSelection::Var(var, path) => {
- let rest = path.pretty_print(indentation)?;
- write!(result, "${var}{rest}")?;
+ let path_string = path.pretty_print(indentation);
+ result.push_str(var.as_str());
+ result.push_str(path_string.as_str());
}
PathSelection::Key(key, path) => {
- let rest = path.pretty_print(indentation)?;
- write!(result, "{key}{rest}")?;
+ let path_string = path.pretty_print(indentation);
+ result.push_str(key.dotted().as_str());
+ result.push_str(path_string.as_str());
}
PathSelection::Selection(sub) => {
- let sub = sub.pretty_print(indentation)?;
- write!(result, " {sub}")?;
+ let sub_string = sub.pretty_print(indentation);
+ result.push(' ');
+ result.push_str(sub_string.as_str());
}
PathSelection::Empty => {}
- }
+ };
- Ok(result)
+ result
}
}
Co-authored-by: Ben Newman <ben@benjamn.com>
Preparation for making pretty_print infallible, as I suggested here: #5248 (comment)
Co-authored-by: Ben Newman <ben@benjamn.com>
Co-authored-by: Ben Newman <ben@benjamn.com>
Fixes an issue where a path with a variable would duplicate the $.
Checklist
Complete the checklist (and note appropriate exceptions) before the PR is marked ready-for-review.
Exceptions
Note any exceptions here
Notes
Footnotes
It may be appropriate to bring upcoming changes to the attention of other (impacted) groups. Please endeavour to do this before seeking PR approval. The mechanism for doing this will vary considerably, so use your judgement as to how and when to do this. ↩
Configuration is an important part of many changes. Where applicable please try to document configuration examples. ↩
Tick whichever testing boxes are applicable. If you are adding Manual Tests, please document the manual testing (extensively) in the Exceptions. ↩