I'm building a tool to lazily apply multiple transformations to a string. Basically I have a Transformer trait that receives a string and returns an Iterator<Item = String>.
i.e. you give it a string and it returns an iterator that when you call next() gives you a lowercase version of the string, then an uppercase one.
I have a struct that receives an unknown number of these Iterators, stores them in a Vec<Box<dyn Iterator<Item = String>>> and does something to them.
However, I wonder if there is a way to avoid so many dynamic dispatch calls to next()
Then different implementers may have different types and you can't support an arbitrary set of implementors without type erasure (by support I mean, store their iterator ouputs in a Vec).
You could support a known set of implementors with an enum.
If possible, could change the trait to use a concrete type as the iterator instead of an associated type, so that all implementors return the same type.
Sometimes it's possible to move the logic that calls next[1] into the trait so that it doesn't happen on a type-erased object. That's probably not possible here if you're interleaving calls to next on different iterators, but might be possible if all your calls to next for a given iterator are grouped.
Thank you for answering ! It took me a while to figure it out. I really didn't need to keep them in a Vec to begin with and managed to implement it using traits and generics. I was a bit confused at first but it became clearer after I looked at how iterator adapters are implemented.
I'm beginning to grasp how powerful traits and generics can be, this language is really cool.
This is how I implemented it in case anyone's interested:
Btw, it is considered idiomatic to omit type bounds where they aren't directly used. In your playground that's the definition and inherent impl for Transformed.