Search code examples
typesrustimage-resizing

Refactor to module creates different type request from compiler?


Why I am getting a compiler request for different types when refactoring this example code to use a wrapper around the resize image library.

Basically resize always seems to be u16 output so why is my change asking for u8 when the original code never required this conversion?

extern crate resize;

use resize::Type;
use resize::Pixel;

pub struct Resize{
    w1:usize,
    h1:usize,
    w2:usize,
    h2:usize,
    src: Vec<u16>,
}

impl Resize {
    pub fn new(
        ow:usize, 
        oh:usize, 
        dw:usize, 
        dh:usize,
        inc: Vec<u16>
    ) -> Resize {
        Resize {
            w1:ow,
            h1:oh,
            w2:dw,
            h2:dh,
            src:inc,
        }
    }

    pub fn run(&self) -> Vec<u16> {
        let mut dst = vec![0;self.w2*self.h2];
        resize::resize(
            self.w1, 
            self.h1, 
            self.w2, 
            self.h2, 
            Pixel::RGBA64, 
            Type::Lanczos3, 
            self.src.as_slice(), 
            &mut dst,
        );
        dst
    }
}

Compiler error message

error[E0308]: mismatched types
  --> src/main.rs:24:45
   |
24 |     let image = Resize::new(w1, h1, w2, h2, src);
   |                                             ^^^ expected u16, found u8
   |
   = note: expected type `std::vec::Vec<u16>`
              found type `std::vec::Vec<u8>`
   = help: here are some functions which might fulfill your needs:
           - .to_vec()

error[E0308]: mismatched types
  --> src/main.rs:30:54
   |
30 |     encoder.write_header().unwrap().write_image_data(dst).unwrap();
   |                                                      ^^^ expected u8, found u16
   |
   = note: expected type `&[u8]`
              found type `&[u16]`

Solution

  • TL;DR: Expected type of src variable is Vec<u16>, but it's set to Vec<u8>, because of type inference.


    Variable src is assigned in line:

    let mut src = vec![0;info.buffer_size()];
    

    It infers the type as Vec<u8> later by calling:

    reader.next_frame(&mut src).unwrap();
    

    or

    resize::resize(w1, h1, w2, h2, Gray8, Triangle, &src, &mut dst);
    

    Because those functions expect type &mut [u8], not &mut [u16].

    If we set expected type Vec<u16> explicitly when assigning src:

    let mut src: Vec<u16> = vec![0; info.buffer_size()];
    

    Now calling next_frame() and resize() will fail because types not match, but compiler will give us better hints what's wrong and what can we do about it.

    error[E0308]: mismatched types
      --> src/main.rs:65:23
       |
    65 |     reader.next_frame(&mut src).unwrap();
       |                       ^^^^^^^^ expected slice, found struct `std::vec::Vec`
       |
       = note: expected type `&mut [u8]`
                  found type `&mut std::vec::Vec<u16>`
       = help: here are some functions which might fulfill your needs:
               - .as_mut_slice()
    
    error[E0308]: mismatched types
      --> src/main.rs:74:53
       |
    74 |     resize::resize(w1, h1, w2, h2, Gray8, Triangle, &src, &mut dst);
       |                                                     ^^^^ expected slice, found struct `std::vec::Vec`
       |
       = note: expected type `&[u8]`
                  found type `&std::vec::Vec<u16>`
       = help: here are some functions which might fulfill your needs:
               - .as_slice()