Declaration type that simulates an interface

In c#/java i would have created an interface and instantiated an object that implments it. In the following code i dont know how to declare the variable based on the returned type.

This same thing would have happened if i would have used the from_path() function.

What is the correct declaration in this situation?
thanks again

dan@dan-VirtualBox:~/Downloads/csvreaders/rustcsvreader$ cargo build --release
   Compiling rustcsvreader v0.1.0 (file:///home/dan/Downloads/csvreaders/rustcsvreader)
error[E0308]: mismatched types
  --> src/main.rs:39:28
   |
39 | 		csv::Reader::from_reader(d)	
   | 		                         ^ expected struct `std::io::Stdin`, found &[u8]
   |
   = note: expected type `std::io::Stdin`
              found type `&[u8]`



	let mut rdr : csv::Reader<_> = 
	if !mmap_open {
		csv::Reader::from_reader(std::io::stdin())
	} else {
		let mmap = match Mmap::open_path("/home/dan/2008.csv", Protection::Read) {
			Ok(mmap) => mmap,
			Err(_) => { println!("mmap open fail"); return ; }
		};
		let d = unsafe { mmap.as_slice() };
		csv::Reader::from_reader(d)	
	};

You'll do something similar to C#/Java in Rust - put the concrete type behind a trait object of std::io::Read.
For example:

let mut rdr : csv::Reader<Box<std::io::Read>> = 
	if !mmap_open {
		csv::Reader::from_reader(Box::new(std::io::stdin()))
	} else {
		let mmap = match Mmap::open_path("/home/dan/2008.csv", Protection::Read) {
			Ok(mmap) => mmap,
			Err(_) => { println!("mmap open fail"); return ; }
		};
		let d = unsafe { mmap.as_slice() };
		csv::Reader::from_reader(Box::new(d))	
	};
1 Like

How did you know that was the trait? I didn't see that in the documentation.

thanks
also i get this now:

let mut rdr : csv::Reader<Box<std::io::Reader>> =  ...

   Compiling rustcsvreader v0.1.0 (file:///home/dan/Downloads/csvreaders/rustcsvreader)
error[E0412]: cannot find type `Reader` in module `std::io`
  --> src/main.rs:30:41
   |
30 | 	let mut rdr : csv::Reader<Box<std::io::Reader>> = 
   | 	                                       ^^^^^^ did you mean `Read`?
   |
   = help: possible candidate is found in another module, you can import it into scope:
             `use csv::Reader;`

Sorry, typo (that I just edited) - it should say csv::Reader<Box<std::io::Read>>, not ...io::Reader

Thanks for the quick followup, That code produces this:

dan@dan-VirtualBox:~/Downloads/csvreaders/rustcsvreader$ cargo build --release
   Compiling rustcsvreader v0.1.0 (file:///home/dan/Downloads/csvreaders/rustcsvreader)
error[E0308]: mismatched types
  --> src/main.rs:32:28
   |
32 | 		csv::Reader::from_reader(std::io::stdin())
   | 		                         ^^^^^^^^^^^^^^^^ expected struct `std::boxed::Box`, found struct `std::io::Stdin`
   |
   = note: expected type `std::boxed::Box<std::io::Read>`
              found type `std::io::Stdin`

error[E0308]: mismatched types
  --> src/main.rs:39:28
   |
39 | 		csv::Reader::from_reader(d)	
   | 		                         ^ expected struct `std::boxed::Box`, found &[u8]
   |
   = note: expected type `std::boxed::Box<std::io::Read>`
              found type `&[u8]`

You're missing the Box::new(...) portions that are in my example.

compiled. i don't understand why that works and how you knew to do that.

thanks

csv::Reader - Rust - if you look right above that function doc you'll see a "impl<R: Read> Reader<R>" heading. That means all the functions doc'd below that heading (and until some other similar heading) are available when R:Read, and from_reader is fn from_reader(rdr: R) -> Reader<R>

io::Read and io::Write are very commonly used as type bounds for (sync) I/O. In Java land, that's roughly equivalent to InputStream and OutputStream.

Which bits? Happy to try and explain any or all of it :slight_smile:

The Box::new(...)

I guess i don't know what Box is or does and how that type can be used interchangably.

Take a look at Using Trait Objects that Allow for Values of Different Types - The Rust Programming Language to start with.