Skip to main content
added 53 characters in body
Source Link
Shepmaster
  • 439.3k
  • 116
  • 1.3k
  • 1.5k

This is the simplest solution but will borrow and lock Stdin.

use std::fs::File; use std::io::{self, ReadBufRead, BufReadRead}; use std::fs::File; struct Input<'a> { source: Box<BufRead + 'a>, } impl<'a> Input<'a> { fn console(stdin: &'a io::Stdin) -> Input<'a> { Input {  source: Box::new(stdin.lock()) },   } }  fn file(path: &str) -> io::Result<Input<'a>> { File::open(path)  .map(|file| Input {  .map(|file| Input { source: Box::new(io::BufReader::new(file)),  }) } } impl<'a> Read for Input<'a> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.source.read(buf) } } impl<'a> BufRead for Input<'a> { fn fill_buf(&mut self) -> io::Result<&[u8]> { self.source.fill_buf() }  fn consume(&mut self, amt: usize) { self.source.consume(amt); } } 

Due to default trait methods, Read and BufRead are fully implemented for Input. So you can call lines on Input.

let input = Input::file("foo.txt").unwrap(); for line in input.lines() { println!("input line: {:?}", line); } 

This is the simplest solution but will borrow and lock Stdin.

use std::io::{self, Read, BufRead}; use std::fs::File; struct Input<'a> { source: Box<BufRead + 'a> } impl<'a> Input<'a> { fn console(stdin: &'a io::Stdin) -> Input<'a> { Input { source: Box::new(stdin.lock()) } } fn file(path: &str) -> io::Result<Input<'a>> { File::open(path)   .map(|file| Input { source: Box::new(io::BufReader::new(file)) }) } } impl<'a> Read for Input<'a> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.source.read(buf) } } impl<'a> BufRead for Input<'a> { fn fill_buf(&mut self) -> io::Result<&[u8]> { self.source.fill_buf() } fn consume(&mut self, amt: usize) { self.source.consume(amt); } } 

Due to default trait methods, Read and BufRead are fully implemented for Input. So you can call lines on Input.

let input = Input::file("foo.txt").unwrap(); for line in input.lines() { println!("input line: {:?}", line); } 

This is the simplest solution but will borrow and lock Stdin.

use std::fs::File; use std::io::{self, BufRead, Read}; struct Input<'a> { source: Box<BufRead + 'a>, } impl<'a> Input<'a> { fn console(stdin: &'a io::Stdin) -> Input<'a> { Input {  source: Box::new(stdin.lock()),   } }  fn file(path: &str) -> io::Result<Input<'a>> { File::open(path).map(|file| Input {  source: Box::new(io::BufReader::new(file)),  }) } } impl<'a> Read for Input<'a> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.source.read(buf) } } impl<'a> BufRead for Input<'a> { fn fill_buf(&mut self) -> io::Result<&[u8]> { self.source.fill_buf() }  fn consume(&mut self, amt: usize) { self.source.consume(amt); } } 

Due to default trait methods, Read and BufRead are fully implemented for Input. So you can call lines on Input.

let input = Input::file("foo.txt").unwrap(); for line in input.lines() { println!("input line: {:?}", line); } 
Source Link
A.B.
  • 16.9k
  • 5
  • 66
  • 67

This is the simplest solution but will borrow and lock Stdin.

use std::io::{self, Read, BufRead}; use std::fs::File; struct Input<'a> { source: Box<BufRead + 'a> } impl<'a> Input<'a> { fn console(stdin: &'a io::Stdin) -> Input<'a> { Input { source: Box::new(stdin.lock()) } } fn file(path: &str) -> io::Result<Input<'a>> { File::open(path) .map(|file| Input { source: Box::new(io::BufReader::new(file)) }) } } impl<'a> Read for Input<'a> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.source.read(buf) } } impl<'a> BufRead for Input<'a> { fn fill_buf(&mut self) -> io::Result<&[u8]> { self.source.fill_buf() } fn consume(&mut self, amt: usize) { self.source.consume(amt); } } 

Due to default trait methods, Read and BufRead are fully implemented for Input. So you can call lines on Input.

let input = Input::file("foo.txt").unwrap(); for line in input.lines() { println!("input line: {:?}", line); }