algs4_rs/
io.rs

1use crate::primitive::{PrimFloat, PrimInt};
2use crate::scanner::Scanner;
3use std::fs::File;
4use std::io::BufReader;
5use std::io::StdinLock;
6use std::io::{self, BufRead};
7use std::ops::{Deref, DerefMut};
8use std::str::FromStr;
9
10/// General Input (stdin, file, socket, etc.).
11pub struct In<B: BufRead> {
12    scanner: Scanner<B>,
13}
14
15impl<B: BufRead> In<B> {
16    /// Creates a new instance of BaseInput.
17    pub fn new(bufread: B) -> Self {
18        In {
19            scanner: Scanner::new(bufread),
20        }
21    }
22
23    /// Returns true if the input stream has more data, returns false otherwise.
24    pub fn is_empty(&mut self) -> bool {
25        match self.scanner.has_next() {
26            Ok(b) => !b,
27            Err(_) => true,
28        }
29    }
30
31    /// Reads an integer from the input stream.
32    ///
33    /// The integer type is one of `i8`, `i16`, `i32`, `i64`, `i128`, `isize`, `u8`, `u16`, `u32`,
34    /// `u64`, `u128`, or `usize`.
35    ///
36    /// # Errors
37    ///
38    /// Same as `Scanner::next_int`.
39    pub fn read_int<T>(&mut self) -> io::Result<T>
40    where
41        T: PrimInt + FromStr,
42    {
43        self.scanner.next_int::<T>()
44    }
45
46    /// Reads a floating point number from the input stream.
47    ///
48    /// The integer type is one of `f32` or `f64`.
49    ///
50    /// # Errors
51    ///
52    /// Same as `Scanner::next_float`.
53    pub fn read_float<T>(&mut self) -> io::Result<T>
54    where
55        T: PrimFloat + FromStr,
56    {
57        self.scanner.next_float::<T>()
58    }
59
60    /// Reads all integers from the input stream using the internal scanner, consuming all the
61    /// content in the input stream, reading the content in a token-by-token streaming mode.
62    ///
63    /// # Errors
64    ///
65    /// Same as `Scanner::next_int`.
66    pub fn read_all_ints<T>(&mut self) -> io::Result<Vec<T>>
67    where
68        T: PrimInt + FromStr,
69    {
70        let mut list = Vec::new();
71        loop {
72            if !self.scanner.has_next()? {
73                break;
74            }
75            list.push(self.scanner.next_int::<T>()?);
76        }
77        Ok(list)
78    }
79
80    /// Read a string token from the input stream.
81    ///
82    /// # Errors
83    ///
84    /// Same as `Scanner::next_token`.
85    pub fn read_string(&mut self) -> io::Result<String> {
86        self.scanner.next_token()
87    }
88
89    /// Reads all string tokens from the input stream using the internal scanner, consuming all the
90    /// content in the input stream, reading the content in a token-by-token streaming mode.
91    ///
92    /// # Errors
93    ///
94    /// Same as `Scanner::next_token`.
95    pub fn read_all_strings(&mut self) -> io::Result<Vec<String>> {
96        let mut list = Vec::new();
97        loop {
98            if !self.scanner.has_next()? {
99                break;
100            }
101            list.push(self.scanner.next_token()?);
102        }
103        Ok(list)
104    }
105}
106
107/// Standard input of this library.
108pub struct StdIn(In<StdinLock<'static>>);
109
110impl Deref for StdIn {
111    type Target = In<StdinLock<'static>>;
112    fn deref(&self) -> &Self::Target {
113        &self.0
114    }
115}
116
117impl DerefMut for StdIn {
118    fn deref_mut(&mut self) -> &mut Self::Target {
119        &mut self.0
120    }
121}
122
123impl StdIn {
124    pub fn new() -> Self {
125        StdIn(In::new(io::stdin().lock()))
126    }
127}
128
129impl Default for StdIn {
130    fn default() -> Self {
131        Self::new()
132    }
133}
134
135/// File input.
136pub struct FileIn(In<BufReader<File>>);
137
138impl Deref for FileIn {
139    type Target = In<BufReader<File>>;
140    fn deref(&self) -> &Self::Target {
141        &self.0
142    }
143}
144
145impl DerefMut for FileIn {
146    fn deref_mut(&mut self) -> &mut Self::Target {
147        &mut self.0
148    }
149}
150
151impl FileIn {
152    /// Creates a new instance of In.
153    pub fn new(path: &str) -> io::Result<Self> {
154        let f = std::fs::File::open(path)?;
155        Ok(FileIn(In::new(BufReader::new(f))))
156    }
157}