Expected enum `std::result::Result`, found `()` when using for loop

Viewed 1470

I'm tinkering with one of the examples from the texture synth project:

use texture_synthesis as ts;

fn main() -> Result<(), ts::Error> {
    //create a new session
    let texsynth = ts::Session::builder()
        //load a single example image
        .add_example(&"imgs/1.jpg")
        .build()?;

    //generate an image
    let generated = texsynth.run(None);

    //save the image to the disk
    generated.save("out/01.jpg")
}

I'd like to repeat this three times using a for loop. This was how I thought I might do it:

use texture_synthesis as ts;

fn main() -> Result<(), ts::Error> {
    for i in 0..3 {
        let texsynth = ts::Session::builder()
            //load a single example image
            .add_example(&"imgs/1.jpg")
            .build()?;

        //generate an image
        let generated = texsynth.run(None);

        //save the image to the disk
        let index: String = i.to_string();
        let outputPath = ["out/", &index, ".jpg"].concat();
        generated.save(outputPath );
    };
}

However this gives me the error:

fn main() -> Result<(), ts::Error> {
  |    ----      ^^^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found `()`        
  |    |
  |    implicitly returns `()` as its body has no tail or `return` expression

This sounds like the main function is throwing an error because it's not getting a result of the type that it wants? How could I fix this?

1 Answers

The main function is defined as fn main() -> Result<(), ts::Error>, which means that it must return a value of type Result<(), ts::Error>. In the original code, this is accomplished by the last line:

generated.save("out/01.jpg")  // Note the absence of semicolon here

because generated.save returns a value of the right type (the return keyword is optional for the last expression of a function in Rust, provided there is no semicolon after the expression).

In order to fix your issue, you will need to ensure that main returns a value of the right type. This requires two changes:

  • If a call to generated.save returns an error, then you should propagate the error. This is accomplished by the ? postfix operator.
  • If the loop finishes succesfully, then you should return a value that signifies that all is well. This value is Ok(()).

Full code:

use texture_synthesis as ts;

fn main() -> Result<(), ts::Error> {
    //create a new session

    for i in 1..3{
        let texsynth = ts::Session::builder()
            //load a single example image
            .add_example(&"imgs/1.jpg")
            .build()?;

        //generate an image
        let generated = texsynth.run(None);

        //save the image to the disk
        let index: String = i.to_string();
        let outputPath = ["out/", &index, ".jpg"].concat();
        generated.save(outputPath)?;
    };

    Ok(())
}
Related