1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Copyright 2019 statiolake <statiolake@gmail.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be copied, modified, or
// distributed except according to those terms.

//! Defines whitespace-splitted token stream wrapping actual stream like stdin.
//!
//! The main is trait `Source`.  This is implemented to the following two type of source:
//!
//! 1. Read entire source at once.  (`once::OnceSource`)
//! 1. Read source line by line.  (`line::LineSource`)
//!
//! `OnceSource` is very fast, while `LineSource` is handy for local debugging. `OnceSource` must
//! read entire input before any other work and you must put EOF (Ctrl-D on Unix or Ctrl-Z on
//! Windows) after input.  LineSource reads source one by one.  Simply press enter to input.
//!
//! There is another source named `auto::AutoSource`.  `AutoSource` is `OnceSource` in release
//! build, is `LineSource` in debug build.  If you use debug build in local testing, `LineSource`,
//! convenience version is used.  In judge server it is compiled in release mode, so `OnceSource`,
//! faster version is used.  This is usually no problem in judging (except interactive problem?).
//!
//! You can specify the source to be used in `input!` as follows:
//!
//! ```
//! # extern crate proconio;
//! use proconio::source::auto::AutoSource;
//! use proconio::input;
//!
//! let source = AutoSource::from("32 54 -23");
//! input! {
//!     from source,
//!     n: u8,
//!     m: u32,
//!     l: i32,
//! }
//!
//! println!("{} {} {}", n, m, l);
//! assert_eq!(n, 32);
//! assert_eq!(m, 54);
//! assert_eq!(l, -23);
//! ```
//!
//! In above example, `OnceSource<BufReader<&[u8]>>` and `LineSource<BufReader<&[u8]>>` implements
//! `From<&str>`, so you can create the source from a string literal.  You can create an instance
//! directly from the value of type implementing `BufRead` by using `OnceSource::new()` and
//! `LineSource::new()`.
//!
//! If you use `input!` macro with no source specified then it uses `AutoSource` with stdin.  So,
//! locally `LineSource` are used, in the server `OnceSource` are used.  `OnceSource` and
//! `LineSource` behaves samely in point of the read result, but, unintentionally, it may differ in
//! a bare possibility. If it should differ, you can manually specify `LineSource` as `source` of
//! `input!`.
use std::any::type_name;
use std::fmt::Debug;
use std::io::BufRead;
use std::str::FromStr;

pub mod line;
pub mod once;
mod tokens;

pub mod auto {
    //! Defines `AutoSource`.
    //!
    //! It is `LineSource` for debug build, `OnceSource` for release build.

    #[cfg(debug_assertions)]
    pub use super::line::LineSource as AutoSource;
    #[cfg(not(debug_assertions))]
    pub use super::once::OnceSource as AutoSource;
}

/// The main trait. Types implementing this trait can be used for source of `input!` macro.
pub trait Source<R: BufRead> {
    /// Gets a whitespace-splitted next token.
    fn next_token(&mut self) -> Option<&str>;

    /// Check if tokens are empty
    #[allow(clippy::wrong_self_convention)]
    fn is_empty(&mut self) -> bool;

    /// Force gets a whitespace-splitted next token.
    fn next_token_unwrap(&mut self) -> &str {
        self.next_token().expect(concat!(
            "failed to get the next token; ",
            "maybe reader reached an end of input. ",
            "ensure that arguments for `input!` macro is correctly ",
            "specified to match the problem input."
        ))
    }
}

// &mut S where S: Source is also source.
impl<R: BufRead, S: Source<R>> Source<R> for &'_ mut S {
    fn next_token(&mut self) -> Option<&str> {
        (*self).next_token()
    }

    fn is_empty(&mut self) -> bool {
        (*self).is_empty()
    }
}

/// A trait representing which type can be read from `Source`.
///
/// If you want to read your own type using `input!`, you can implement this trait for your type.
/// Alternatively, you can add `#[derive_readable]` if you put `use
/// proconio_derive::derive_readable` in your source.  It automatically implements `Readable` if
/// all members of your type are `Readable`.
pub trait Readable {
    type Output;
    fn read<R: BufRead, S: Source<R>>(source: &mut S) -> Self::Output;
}

// implementations of Readable for any `FromStr` types including primitives.
impl<T: FromStr> Readable for T
where
    T::Err: Debug,
{
    type Output = T;
    fn read<R: BufRead, S: Source<R>>(source: &mut S) -> T {
        let token = source.next_token_unwrap();
        match token.parse() {
            Ok(v) => v,
            Err(e) => panic!(
                concat!(
                    "failed to parse the input `{input}` ",
                    "to the value of type `{ty}`: {err:?}; ",
                    "ensure that the input format is collectly specified ",
                    "and that the input value must handle specified type.",
                ),
                input = token,
                ty = type_name::<T>(),
                err = e,
            ),
        }
    }
}