Hello :)
Thanks for this nice crate!
To give more context for this discussion, I'm working on a personal library that implements a `WebRender` struct and I'd like it to compose an embedded directory.
```rust
struct WebRender {
dir: Box<dyn RustEmbed>
}
```
fails with
```
error[E0038]: the trait `rust_embed::RustEmbed` is not dyn compatible
|
236 | dir: Box<dyn RustEmbed>
| ^^^^^^^^^^^^^ `rust_embed::RustEmbed` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
|
48 | fn get(file_path: &str) -> Option<EmbeddedFile>;
| ^^^ the trait is not dyn compatible because associated function `get` has no `self` parameter
...
57 | fn iter() -> impl Iterator<Item = std::borrow::Cow<'static, str>> + 'static;
| ^^^^ the trait is not dyn compatible because associated function `iter` has no `self` parameter
```
I don't want to use generics and static dispatch in this part of the code, so I've worked around this by introducing my own dyn-compatible trait and implementing it for all embedded types:
```rust
trait RustEmbedDynCompatible {
fn get(&self, file_path: &str) -> Option<EmbeddedFile>;
fn names(&self) -> Vec<Cow<'static, str>>;
}
impl<T: RustEmbed> RustEmbedDynCompatible for T {
fn get(&self, file_path: &str) -> Option<EmbeddedFile> {
T::get(file_path)
}
fn names(&self) -> Vec<Cow<'static, str>> {
T::iter().collect()
}
}
```
The methods take `&self` and the return of `iter()` changes to something concrete (I'm using a `Vec`). I've also renamed `iter()` to avoid confusion since it does not produce an iterator.
and it works :)
```rust
#[derive(Embed)]
#[folder = "."]
struct ExampleFolder;
let web_render = WebRender {
dir: Box::new(ExampleFolder),
};
```
My question for the maintainers of this crate: does the use-case of dyn-compatible makes sense to integrate in the crate?
If yes, how to go about it? Some example solutions:
- change the current `RustEmbed` trait in a backwards-incompatible way to make it like the example `RustEmbedDynCompatible` above
- change the current `RustEmbed` to the two dyn-compatible equivalent methods and restrict the current two with `where Self: Sized`
- introduce a new trait like the example above
If no, maybe we can update the documentation of the trait to mention that the user can create their own trait like above to work around the restriction?
I'd love to contribute with the solution (code and docs), but the design requires some further feedback from the maintainers and community.
Best regards,
Gui