How to choose a suitable struct/trait system to represent keyword/value pairs for arbitrary value types

Hi everyone!
I'm new to rust and have been struggling with understanding the Type/Trait/Struct system that rust uses.

I'm trying to implement the following idea for a toy/learning project of mine. I am an astronomy grad student, so I have to work a lot with FITS binary image files, so I thought it would be fun to try to write a library to read those FITS files.

Anyway, those files contain 80-byte keywords consisting of a name (string) and some generic type (int, float, complex number, bool, whatever). I thought it would be a good idea to represent these with a struct that has a generic type value field, like this:

pub struct Keyword<Type> {
    name: String,
    value: Type
}

My issue is that I want to use these structs in higher abstraction layers. For instance, a FITS Header Data Unit (HDU) contains 36 Keywords. For most of these keywords, you don't know which type you're gonna get beforehand.

This led me to try to use a vector of trait objects. I made two different traits to this end, but neither works, for different reasons.

(1) Adding a generic type function

pub trait AbstractKeyWord {
    fn name(&self) -> Box<String>;
    fn val<Type>(&self) -> Box<Type>;
}

This does not work, the compiler gives me an error saying that this trait cannot be used to create an Object.

(2) using a type keyword

pub trait AbstractKeyWord {
    type Type;
    fn name(&self) -> Box<String>;
    fn val(&self) -> Box<Type>;
}

This also doesn't work. This time, the complier wants me to specify a vector of dynamic trait objects with a specific type, which is useless in my case, since I want to be able to mix keywords with different value types. Specifically:

other: Option<Vec<Box<dyn AbstractKeyWord>>>

Is not allowed by the complier.

Those two options were the only ones I could think of, besides just using a vector of bytes to represent all types (which would be cursed).

Anyway, does anyone know how to solve this "à la rust"? I think I might be stuck in an OO thinking pattern since I am used to writing code in OO languages.

Any help would be appreciated!

This is probably a situation where an enum is more appropriate. Alternatively, you could have a trait with attempt-to-extract methods for every type of field, but it doesn't seem very beneficial to me given the information at hand. (This would be like "manually monomorphizing" your val method to make it non-generic; a method per type.)

Incidentally there's no reason to box the String or Type returns.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.