-
-
Notifications
You must be signed in to change notification settings - Fork 89
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
Implement traits for slices, arrays, and tuples #735
base: master
Are you sure you want to change the base?
Implement traits for slices, arrays, and tuples #735
Conversation
core/src/drawable.rs
Outdated
pub struct Pixel<C>(pub Point, pub C) | ||
where | ||
C: PixelColor; | ||
impl<T: Drawable> Drawable for &T { |
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.
What about making drawing work on slices?
// add ?Sized
impl<T: Drawable + ?Sized> Drawable for &T {...}
// add this impl
impl<T: Drawable> Drawable for [T] {...}
I saw [T]
impls for other traits but not Drawable, and all of the reference impls could have ?Sized
added.
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.
Drawable
, unfortunately, cannot be implemented for slices without either:
- changing the trait (did not want to introduce any breaking changes in this PR)
- having the associated
Output
type of theDrawable
trait not be meaningful, or lossy, when implemented on slices.
This is the same for the lack of slice implementations on other traits which return a success value from one or more of their trait methods.
With respect to the ?Sized
addition, I'd be fine to add this for the traits and implementations in which it makes sense and it feels like a worthwhile change
Interesting, but I'm a bit hesitant to add so many trait implementations for generic types. In my projects the |
Can you elaborate on what may be causing the hesitation? The implementations for Tuples, Slices, and Arrays are all added as a means to group homogeneous or non-homogeneous items and perform operations across the group. These are implementations that cannot be done outside of this crate without introducing new traits or types, which has the ramification of fragmenting the embedded graphics ecosystem. Using Tuples, Slices, or Arrays also enables developers to write much more succinct and maintainable code. A simple toy example of this can be seen here: Beyond this, I've been exploring writing a layout crate heavily inspired by embedded-layout. My goal for this project has been to provide an API that looks something along the lines of: let view = Column(
Layout::TightCenter,
(
text,
Row(Layout::SpaceBetween, (triangle, circle)),
(triangle2, circle2)
)
); which would be analogous to embedded-layout's let view = LinearLayout::vertical(
Chain::new(text)
.append(LinearLayout::horizontal(Chain::new(triangle).append(circle)).arrange())
.append(
Chain::new(triangle2.align_to(&circle2, horizontal::Center, vertical::Top))
.append(circle2),
),
)
.with_alignment(horizontal::Center)
.arrange(); However, currently because of the lack of support for any sort of grouping within e-g utilizing core primitives I would need to fall back to providing some sort of collection type - just like embedded-layout has done with their I think it is also worth mentioning that collections of types would imply that more of the graphical elements are stored in memory at any one time, causing an increase in memory utilization. Personally, I don't see this as a issue given that this change in no way would preclude individuals from writing custom composite elements that internally utilize short-lived primitives, just like is done today. |
Not really, it just seemed like a lot of changes and I want to be sure we don't make any changes that could cause issues in the future. But perhaps this is only caused by the fact that I haven't done a lot of Rust development lately and I'm extra cautious. Thanks for the great explanation. I didn't have time to look into this in detail yet, but I think it would be better to split this into two PRs, one for the trait implementations for references and another for the arrays and tuples. IMO the trait impls for refeferences could be merged first and the collections might need some more discussion. I would also like to hear @jamwaffles opinion on the impls for the collections. |
Went ahead and split this into 2 PRs, with #736 housing the implementations for references. I'd be happy to answer any other questions as well or share the small layout crate, if that would help. Otherwise I look forward to hearing the others thoughts |
Thank you for helping out with embedded-graphics development! Please:
CHANGELOG.md
entry in the Unreleased section under the appropriate heading (Added, Fixed, etc) if your changes affect the public APIrustfmt
on the projectjust build
(Linux/macOS only) and make sure it passes. If you use Windows, check that CI passes once you've opened the PR.PR description
When evaluating e-g and related crates, it was noticed that working with collections of items required either writing a custom composite type or relying on a crate's own custom solution (such as
embedded-layout
's pseudo-linked listChain
). My impression was that this felt cumbersome and lead to overly verbose code, especially when attempting to do some basic rapid prototypes.This PR implements many of the core traits for slices, arrays, tuples (up to 12 items),
&T
and&mut T
, where appropriate and possible.The main driver for this change is to enable better support for both homogeneous and non-homogeneous collections of elements that can be treated as if they were a single logical graphical element. This should also enable higher level crates to more easily support collections (again, both homogeneous and non-homogeneous) without the need for custom collection types or dynamic dispatch.
EDIT: this PR has been split and the implementations for references is now housed in #736