I'm working on a Rust trait, LayoutSection, and ran into an issue where I had to make two nearly identical functions for the trait: one that's an associated function and one thats a method: section_type() and section_kind(&self).
Ideally, I would only have the section_type() associated function, however LayoutSection is unable to be made into a trait object unless section_type() has a where Self: Sized clause.
However I need to use section_type() in methods that use trait objects, so I was forced to create section_kind(&self), which is exactly the same as section_type(), but it can be called on trait objects.
I know this is a horrible hack, and there has to be some alternative, but I can't think of any other way to do this.
Here is a simplified example of how these functions are defined and being used: (here's the Rust Playground)
fn main() {
print_generic_info::<Header>(None);
}
fn print_generic_info<S: LayoutSection>(game: Option<Game>) {
if let Some(s) = game {
let section = s.get_section::<S>();
}
// The reason I wanted to use a type parameter in `Game::get_section`,
// rather than pass a `SectionType`, is because I'm doing something
// like this later on:
// let section = <S as LayoutSection>::with_offset(...);
}
struct Game;
impl Game {
fn get_section<S: LayoutSection>(&self) -> Option<&LayoutSection> {
Some(match <S as LayoutSection>::section_type() {
SectionType::Header => unimplemented!(),
})
}
}
#[derive(Debug)]
enum SectionType {
Header
}
trait LayoutSection {
fn section_kind(&self) -> SectionType;
fn section_type() -> SectionType
where
Self: Sized;
fn print_generic_info(&self) {
println!("Type: {:?}", self.section_kind());
}
}
struct Header;
impl LayoutSection for Header {
fn section_kind(&self) -> SectionType {
SectionType::Header
}
fn section_type() -> SectionType {
SectionType::Header
}
}
What would be a better alternative to this? I wanted to use an associated constant to store the SectionType, however using those still wouldn't allow LayoutSection to be used as a trait object. But something like that would be even better than the section_type() associated function.