I'm writing a program which parses a number of files. These files can fall into a number of different categories and I don't know which in advance. I makes sense to create a type for each type of data the files can contain, but I'm struggling with getting this datatype out of my parser and into my model/main program.
In most other programming languages I would probably define a function/method which accepts a filename as input, and return a generic type as output. Depending on my need I would then cast or test the type of my generic returntype and get the real type of my retuned data.
However, this doesn't really seem to work in Rust. I can define a function which returns a Trait like this:
fn parse_file(file: &'str) -> impl ParsedData
where ParsedData is a common Trait for all my DataTypes. But what do I do from here? At some point I need to seperate the different types of data hidden behind my ParsedData Trait.
Solution 1: I have found the Any trait which does make it possible to downcast a Trait to a type. But the general consensus seems to be that this is something you should avoid. I'm not sure I understand exactly why people don't like it, but if nothing else it seems to be quite a lot of work/boiler plate code to get working.
Solution 2: There is also the possibility of stuffing all the known datatypes into one big containertype, like this:
pub struct DataContainer {
pub data_type_1: Option<DataType1>,
pub data_type_2: Option<DataType2>,
pub data_type_3: Option<DataType3>,
pub data_type_4: Option<DataType4>,
}
fn parse_file(file: &'str) -> DataContainer
and the just pass that around until you need the datatypes inside of it.
Solution n: There seem to be a number of less popular solutions out there
Reading some data without knowing the type in advance must be a very common task. Isn't there a de facto way to deal with it? I read several times that the main reason downcasting suppport in Rust is poor is due to the fact that there are other, and better, way to deal with almost/every single type of problem where people run into the need of downcasting data.
So here is my question. How do you deal with this problem in an easy idiomatic way?
Problem definition:
- Lets say you want to read a number of files. Some will contain user profiles, some will contain pictures (not tied to a user) and some will contain cooking recipes.
- You do not know what a file contains before you read it, but it's easy to parse and there is no uncertainty.
- I defined a function
parse_fileabove, but that was just me thinking that would be a nice interface to reading these files since they probably share a lot of code for opening the file etc.