Run a generic method for every variant of an enum


#1

I’m writing image manipulation library that supports various pixel formats, so I have related types such as RGB<u8>, RGBA<u8>, RGB<u16>, RGBA<u16> and I’m implementing traits for all of these types.

Some library methods need to return an image that can be in any of these formats (varying at runtime), and for that I have an enum: enum Image(RGB8(Vec<RGB<u8>>), RGBA8(Vec<RGBA<u8>>), RGB16(Vec<RGB<u16>>).

This leads to a common, very repetitive pattern where I do a match on the enum, and want to apply the same operation to every variant of the enum:

match image {
    RGB8(data) => data.do_stuff(args),
    RGB16(data) => data.do_stuff(args),
    RGBA8(data) => data.do_stuff(args),
    RGBA16(data) => data.do_stuff(args),
}

or

match image {
    RGB8(data) => Image::RGB8(data.transform_stuff(args)),
    RGB16(data) => Image::RGB16(data.transform_stuff(args)),
    RGBA8(data) => Image::RGBA8(data.transform_stuff(args)),
    RGBA16(data) => Image::RGBA16(data.transform_stuff(args)),
}

Is that the right approach? Apart from macros, is there a way to replace these match expressions with 1-liners in Rust?


#2

At least syntactically you should be able to save some characters by using | like here.
But if they all have the field data, don’t they perhaps offer a more generic way of getting to it? like a data() getter or something?


#3

That’s precisely the thing that I don’t know :slight_smile:

I suppose I need dynamic dispatch here. Is there some glue that turns enum variants into trait objects? (I’m hazy on the details of trait objects)


#4

See the EnumInnerAsTrait! macro (example in the docs) in enum_derive.