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.