rinput/
lib.rs

1use std::{
2    io::stdin,
3    str::FromStr,
4    sync::{Mutex, MutexGuard},
5};
6
7type Buffer = Vec<String>;
8
9/// 从 [`Buffer`] 中解析值
10///
11/// [`Buffer`] 是一个 [`Vec<String>`] 的可变借用
12///
13/// 你也可以为你的类型实现 [`FromStr`],
14/// 所有实现 [`FromStr`] 的类型都会自动实现 [`FromBuf`]
15pub trait FromBuf: Sized {
16    type Err;
17
18    /// 将输入流解析为此类型的值
19    ///
20    /// # Examples
21    /// ```
22    /// let mut buf = vec!["123", "abc"];
23    /// let n = i32::from_buf(&mut buf).unwrap();
24    ///
25    /// assert_eq!(123, n);
26    /// assert_eq!(vec!["abc"], buf);
27    /// ```
28    fn from_buf(b: &mut Buffer) -> Result<Self, Self::Err>;
29}
30
31impl<T: FromStr> FromBuf for T {
32    type Err = T::Err;
33
34    fn from_buf(b: &mut Buffer) -> Result<Self, Self::Err> {
35        T::from_str(b.remove(0).as_str())
36    }
37}
38
39/// 输入流
40pub struct InputStream {
41    buf_mutex: Mutex<Buffer>,
42}
43
44impl InputStream {
45    const fn new() -> Self {
46        Self {
47            buf_mutex: Mutex::new(Buffer::new()),
48        }
49    }
50
51    fn get_buf(&self) -> MutexGuard<Vec<String>> {
52        let mut buf = self.buf_mutex.lock().unwrap();
53        if buf.is_empty() {
54            let mut temp_str = String::new();
55            stdin().read_line(&mut temp_str).unwrap();
56            buf.extend(
57                temp_str
58                    .trim()
59                    .split_ascii_whitespace()
60                    .map(|s| String::from_str(s).unwrap()),
61            );
62        }
63        buf
64    }
65
66    /// 从输入流中解析一个类型为 [`T`] 的值
67    ///
68    /// [`T`] 需要实现 [`FromBuf`] 和 [`Default`]
69    pub fn read<T: FromBuf + Default>(&self) -> T {
70        T::from_buf(&mut self.get_buf()).unwrap_or_default()
71    }
72
73    /// 读取流中的下一个字符串
74    pub fn read_str(&self) -> String {
75        self.get_buf().remove(0)
76    }
77
78    /// 读取流中的下一个字符
79    pub fn read_char(&self) -> char {
80        let mut buf = self.get_buf();
81        let c = buf[0].remove(0);
82        if buf[0].is_empty() {
83            buf.remove(0);
84        }
85        c
86    }
87}
88
89/// 全局输入流
90///
91/// 查看 [`InputStream`]
92#[allow(non_upper_case_globals)]
93pub static rin: InputStream = InputStream::new();
94
95/// 声明并从控制台输入变量
96///
97/// 使用 [`rinput::rin.read()`][read] 输入
98///
99/// [read]: InputStream
100///
101/// # Panics
102/// 如果 [`io::stdin`] 读入失败
103///
104/// [`io::stdin`]: std::io::stdin
105///
106/// # Examples
107///
108/// ```
109/// use rinput::input;
110///
111/// input!(n: u8);
112/// input!(a: i32, mut c: char, s: String);
113/// ```
114#[macro_export]
115macro_rules! input {
116    (mut $name:ident : $type:ty) => {
117        let mut $name: $type = rinput::rin.read();
118    };
119
120    ($name:ident : $type:ty) => {
121        let $name: $type = rinput::rin.read();
122    };
123
124    (mut $name:ident : $type:ty, $($tail:tt)+) => {
125        input!(mut $name:$type);
126        input!($($tail)+);
127    };
128
129    ($name:ident : $type:ty, $($tail:tt)+) => {
130        input!($name:$type);
131        input!($($tail)+);
132    };
133}