Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
653 views
in Technique[技术] by (71.8m points)

rust - Multiple return types from a method

I am trying to write a simple TV-episode file renamer in Rust.

A filename is parsed, and might be one of several types (date-based, season/episode-number based etc). This parsed file is then turned into a "populated file" with data from a database (which is then formatted into a new filename)

Initially I tried having the parse method take a filename and return an enum variant:

enum ParsedFile{
    DateBased{series: String, date: Date},
    SeasonBased{series: String, season: i32, episode: i32},
    // etc
}


fn parse(fname:&str) -> Option<ParsedFile>{
    ...
}

This worked fine, however the methods to take the ParsedFile and do different things for each episode became messy

For example, to separate the ParsedFile->PopulatedFile translation into separate methods, I have to match the variants, then destructure this in the method

struct PopulatedFile {
    seriesname: String,
    season: i32,
    episode: i32,
    episodename: String,
    airdate: Date,
}

fn _populate_seasonbased(file: ParsedFile) -> Result<PopulatedFile, TvdbError>{
    // can't just access file.season or file.episode, have to destructure enum again
}

fn populate(f: ParsedFile) -> Result<PopulatedFile, TvdbError> {
    return match f {
        ParsedFile::DateBased{..} => 
            _populate_datebased(f),
        // ...
    }
}

This seemed really clunky, and I'm sure there must be a better way.

It would be nicer to have each episode type as a separate struct, e.g:

struct DateBased{
    series: String,
    date: Date
}
struct SeasonBased{
    series: String,
    season: i32,
    episode: i32
}

..then I could, say, implement a ToPopulatedFile trait for each episode type. However I couldn't find a way to write the parse method in this example (i.e write a method which might return a DateBased struct or a SeasonBased struct)

Is there a good way to structure this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could design a solution around trait, but it would probably be much more work than simply adapting your current solution slightly:

struct DateBased{
    series: String,
    date: Date
}

struct SeasonBased{
    series: String,
    season: i32,
    episode: i32
}

enum ParsedFile{
    Date(DateBased),
    Season(SeasonBased),
    // etc
}

fn _populate_datebased(file: DateBased) -> Result<PopulatedFile, TvdbError>;

fn _populate_seasonbased(file: SeasonBased) -> Result<PopulatedFile, TvdbError>;

fn populate(f: ParsedFile) -> Result<PopulatedFile, TvdbError> {
    return match f {
        ParsedFile::Date(d) => _populate_datebased(d),
        // ...
    }
}

You can combine enum and struct in Rust, and I personally find it worth it to put name on things specifically because it allows manipulating them more easily.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...