Traits as return value from function

I have two enumerations, NormalColour and BoldColour , both of which implement the Colour trait. They contain Blue , BoldGreen , etc.

I would like to return the values ​​of both of these types from the same function, treating them as if they were just a Colour value, calling the paint function for the result, but I cannot find a way to force Rust complier to do this for me. I would like to write something like this:

 pub trait Colour { fn paint(&self, input: &str) -> String; } fn file_colour(stat: &io::FileStat) -> Colour { if stat.kind == io::TypeDirectory { Blue } else if stat.perm & io::UserExecute == io::UserExecute { BoldGreen } else { White } } 

What type should I make the function return to work?

In the end, I want to make more types that implement Colour , so I'm not interested in just turning two enumerations into one big jumper.

+8
source share
2 answers

The answer is object objects. This means that you will work with Box<Colour> as your type; naked Colour not a real type. You can use Box<T> objects for Box<Colour> using the as operator: Box::new(NormalColour::White) as Box<Colour> . In many places, this is not necessary (just write Box::new(NormalColour::White) , and it can be automatically enforced using Box<Colour> ), but sometimes it will still be necessary.

However, if you can do this as an enumeration, this is likely to be a more pleasant solution.

+6
source

The answer above suggests:

 fn file_colour(stat: &io::FileStat) -> Box<Colour> { /* ... */ } 

which works, but you need to wrap all return values ​​in a call to Box::new() .

However, in Rust 1.26 we can now say

 fn file_colour(stat: &io::FileStat) -> impl Colour { /* ... */ } 

and just return the value. Box needed.

+1
source

All Articles