Allow downcasting dyn Element or take Box<dyn Elements>

Applications currently cannot dynamically generate different types of Elements as they need to be passed to a function that is generic over E: Element and it is not possible for a library user to downcast a dyn Element to a specific Element.

I think it would make sense to implement downcast methods (probably using downcast) or have methods take Box<dyn Element> directly however the overhead the latter would cause for the case where the discrete type is known may not be acceptable in this case.

Assigned to
2 years ago
1 year, 9 months ago

~soruh 2 years ago

Actually, it would be possible for a user to do this by creating a new, downcastable, trait and implementing it for every instance of Element so feel free to close this issue if you feel that this is the most appropriate solution.

~ireas 2 years ago

Thanks for bringing this up!

There are two distinct cases: containers (LinearLayout, TableLayout) and wrappers (StyledElement, ...). For containers, the elements are stored in a Box anyway, so it should be possible to add boxed elements. I don’t want to change the argument type of the existing methods because that would make them harder to use, but I think we should add new methods for adding boxed elements, e. g. push_box. Would that work for you?

~soruh 2 years ago

Having push_box in some cases but not in others seems a bit unfortunate but I think it makes the most sense. Especially since the Elements need to be unboxed anyways if they are not stored in a Box internally.

~ireas 2 years ago

To be clear, I’m not against adding boxed methods for the wrappers. But I first have to think about the consequences of that change, whereas it is a no-brainer for the containers as we already use boxed elements anyway.

~ireas 1 year, 9 months ago

The easiest solution would be to change the method signature from

fn push<E: Element + 'static>(&mut self, element: E) {}


fn push<E: Into<Box<dyn Element>>>(&mut self, element: E) {}

but unfortunately, that does not work because Box<dyn Element> does not implement From<T: Element>. An alternative would be to introduce a IntoBoxedElement helper trait similar to cursive’s IntoBoxedView. But as we already have quite a lot of breaking changes for the v0.2.0 release, I’d rather postpone that to the next release.

~ireas REPORTED IMPLEMENTED 1 year, 9 months ago

I’ve introduced the IntoBoxedElement trait and changed Document, LinearLayout and TableLayoutRow to accept implementors of that trait (instead of Element) in commit d086145acb0ad6e03c8331dd83e00f7a1c80511c. We might want to change the wrapper types to use boxes instead of type parameters too – I’ve created #35 for that.

Register here or Log in to comment, or comment via email.