Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resolve "expected (), found Result" when returning a custom result?

Tags:

rust

I am creating a custom Result such that the the Ok value is generic, but I get the following error:

error[E0308]: mismatched types
  --> src/main.rs:38:13
   |
38 |             Err(Error::new(ErrorKind::Other, "Not a subset"))
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found enum `std::result::Result`
   |
   = note: expected type `()`
              found type `std::result::Result<_, std::io::Error>`

With this code:

use std::io;
use std::io::{Error, ErrorKind};

pub type SubsetResult<T> = Result<T, SubsetError>;

#[derive(Debug)]
pub enum SubsetError {
    Io(io::Error),
}

impl From<io::Error> for SubsetError {
    fn from(err: io::Error) -> SubsetError {
        SubsetError::Io(err)
    }
}

trait Subset {
    type T;
    fn is_subset(&self, &[i32]) -> SubsetResult<Self::T>;
}

#[derive(Debug)]
struct Set {
    dataset: Vec<i32>,
}

impl Subset for Set {
    type T = bool;

    // self is the superset
    fn is_subset(&self, subset: &[i32]) -> SubsetResult<Self::T> {
        let mut concatedsets = Vec::new();
        concatedsets.extend_from_slice(self.dataset.as_slice());
        concatedsets.extend_from_slice(subset);
        concatedsets.sort();
        concatedsets.dedup();
        if concatedsets.len() != self.dataset.len() {
            Err(Error::new(ErrorKind::Other, "Not a subset"))
        }
        Ok(true)
    }
}


fn main() {
    let superset = Set { dataset: vec![1, 2, 3, 4, 5] };
    let subset = vec![1, 2, 4];
    let result = superset.is_subset(subset.as_slice()).unwrap();
    println!("{}", result);

}

(Playground)

like image 945
rpiper Avatar asked Aug 17 '16 16:08

rpiper


2 Answers

Note that the error message is because you aren't returning the Err from the function. You simply create it and it becomes the value of the if block. Because there is no else block, the type of the else block is (), so the value of the if expression is indeterminate: is it () or a Result?

You could either return the Err or provide an else block:

if concatedsets.len() != self.dataset.len() {
    Err(Error::new(ErrorKind::Other, "Not a subset"))
} else {
    Ok(true)
}

That unlocks another error, which is that you aren't returning the type you say you are. An Error is not a SubsetError. Because you've implemented From for that error type, you can use try! or ? to convert between types:

Err(Error::new(ErrorKind::Other, "Not a subset"))?

You can also explicitly wrap the type, as shown in squiguy's answer.

like image 140
Shepmaster Avatar answered Nov 19 '22 04:11

Shepmaster


Since your custom error type wraps the IO error type, you must set that in your Err result. And in order for the correct type to be returned you need an explicit return statement as well.

This is what it should look like:

return Err(SubsetError::Io(Error::new(ErrorKind::Other, "Not a subset")));
like image 45
squiguy Avatar answered Nov 19 '22 04:11

squiguy