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

Replace impl Into<String> with impl ToString #302

Merged
merged 3 commits into from
Apr 29, 2021

Conversation

davidpdrsn
Copy link
Contributor

This is something I ran into today. Types that implement
std::fmt::Display cannot be passed to functions that take
impl Into<String>. You have to call display_thing.to_string().
Its a small thing but would be avoided by instead taking impl ToString.

Afaik impl ToString is a superset of impl Into<String>, unless users
manually implement Into<String> for T (or From<T> for String) for
their own types. However I think its more common to implement Display
as that works with println and friends. The main difference is that
Display::fmt can return errors but thats also quite rare in my
experience.

I did some testing in a playground and seems to work.

This is something I ran into today. Types that implement
`std::fmt::Display` cannot be passed to functions that take `impl
Into<String>`. You have to call `display_thing.to_string()`. Its a small
thing but would be fixed by instead taking `impl ToString`.

Afaik `impl ToString` is a superset of `impl Into<String>`, unless users
manually implement `Into<String> for T` (or `From<T> for String`) for
their own types. However I think its more common to implement `Display`
as that works with `println` and friends. The main difference is that
`Display::fmt` can return errors but thats also quite rare in my
experience.

I did some testing in a [playground] and seems to work.

[playground]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1111e071f6ae416ae2688d58d2e9b575
@emilk
Copy link
Owner

emilk commented Apr 12, 2021

Thanks for the PR!

A common use case is ui.label(format!("answer: {}", 42)); which will pass in a String. With this PR, the string will need an additional clone (since to_string takes a &self).

The ergonomic win may outweigh this, but I think we should create a micro-benchmark for the label + format case and check what the added cost is before we merge this.

@davidpdrsn
Copy link
Contributor Author

With this PR, the string will need an additional clone (since to_string takes a &self).

Ah yeah thats true. I didn't consider that.

Would you add a benchmark here https://github.com/emilk/egui/blob/master/egui_demo_lib/benches/benchmark.rs?

@emilk
Copy link
Owner

emilk commented Apr 13, 2021

Yeah! I think it would be good to bench both ui.label("hello world"); and ui.label("hello world".to_string());.

There is also a possibility that, in a separate PR, I can remove the need for a String completely, and allow e.g. impl AsRef<str> or whatever would be the suitable alternative. When that day comes it would be good to have an idea of what the performance implications would be. Maybe impl ToString is always gonna be the most ergonomic, and the perf hit is worth it.

emilk added a commit that referenced this pull request Apr 18, 2021
This is to help evaluate the impact of
#302
@emilk
Copy link
Owner

emilk commented Apr 18, 2021

In my benchmark the ui.label(format!("…")); becomes around 6% slower with this PR, which I think is acceptable. If you get the CI green, I'll merge it!

EmbersArc added a commit to EmbersArc/egui that referenced this pull request Apr 18, 2021
@davidpdrsn
Copy link
Contributor Author

Awesome!

I looked into the clippy warnings and most of them are along the lines of

error: this argument is passed by value, but not consumed in the function body
   --> egui/src/widgets/text_edit.rs:207:43
    |
207 |     pub fn hint_text(mut self, hint_text: impl ToString) -> Self {
    |                                           ^^^^^^^^^^^^^ help: consider taking a reference instead: `&impl ToString`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_value

Supporting that lint would require changing all the callsites to use &thing instead of `thing which would be a breaking change.

@emilk What do you think about this? Should I add #[allow(...)] to the places where the lint fails or is it a breaking change you'd be okay with? I would personally go for adding #[allow(...)] to the methods that takes impl ToString but its of course up to you.

@emilk
Copy link
Owner

emilk commented Apr 19, 2021

Yeah, mute it. The point of this PR is an ergonomic win, so forcing people to write &format!(…) would be against the purpose.

emilk added a commit that referenced this pull request Apr 21, 2021
* drag and zoom support for plots

* update doctest

* use impl ToString

* revert back to Into<String> until #302 is solved

* Apply suggestions from code review

Co-authored-by: ilya sheprut <optitel223@gmail.com>

* use persistence feature for PlotMemory

* rename shift -> translate

* remove automatic bounds

* removed unused methods

* Into<String> -> ToString

* Apply suggestions from code review

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>

* avoid potential invalid bounds bug

* use new is_valid method

* improve auto bounds behavior as suggested

* use NOTHING to initialize min_auto_bounds

Co-authored-by: ilya sheprut <optitel223@gmail.com>
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
emilk added a commit that referenced this pull request Apr 24, 2021
* drag and zoom support for plots

* update doctest

* use impl ToString

* revert back to Into<String> until #302 is solved

* Apply suggestions from code review

Co-authored-by: ilya sheprut <optitel223@gmail.com>

* use persistence feature for PlotMemory

* * split plot into multiple files
* add curve from function
* move more functionality into ScreenTransform struct

* changes from code review in base branch

* let user specify a range for generated functions

* rename file

* minor changes

* improve generator functionality

* improve callback and add parametric callback

* minor changes

* add documentation

* fix merge issues

* changes based on review

* rename folder

* make plot.rs the mod.rs file

* remove mod.rs

* rename file

* namespace changes

* fix doctest

* Update egui/src/widgets/plot/items.rs

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>

Co-authored-by: ilya sheprut <optitel223@gmail.com>
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
@davidpdrsn
Copy link
Contributor Author

Done!

@emilk emilk merged commit 02a62d1 into emilk:master Apr 29, 2021
@emilk
Copy link
Owner

emilk commented Apr 29, 2021

Thanks!

@davidpdrsn davidpdrsn deleted the to-string branch April 29, 2021 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants