Skip to content

Commit

Permalink
Update type names and documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
TheVeryDarkness committed Sep 3, 2024
1 parent 65e812c commit 0e6348a
Show file tree
Hide file tree
Showing 18 changed files with 135 additions and 94 deletions.
13 changes: 13 additions & 0 deletions examples/doc_get_line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,27 @@ use iof::{get_line, read};

fn main() {
// Read a single string from input.
//
// v
// 42
// abc
let s: String = read!();
assert_eq!(s, "42");

// Read a line of string from input.
// Before reading, the cursor is at the end of the previous line.
// Therefore, it reads an empty string.
//
// v
// 42
// abc
let s: String = get_line();
assert_eq!(s, "");

// Read a line of string from input.
//
// v
// abc
let s: String = get_line();
assert_eq!(s, "abc");
}
10 changes: 10 additions & 0 deletions examples/doc_get_line_some.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@ use iof::{get_line_some, read};

fn main() {
// Read a single string from input.
//
// v
// 42
// abc
let s: String = read!();
assert_eq!(s, "42");

// Read a non-empty line of string from input.
// Before reading, the cursor is at the end of the previous line.
// However, as the function name implies, it will repeatedly read lines until a non-empty line is found.
//
// v
// 42
// abc
let s: String = get_line_some();
assert_eq!(s, "abc");
}
37 changes: 35 additions & 2 deletions examples/doc_read.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,70 @@
use iof::{read, Mat};

/// Some examples of reading from standard input.
///
/// We use a `v` to indicate the cursor position.
fn main() {
// Read a single integer from input.
//
// v
// 42 abc def
let n: u32 = read!();
assert_eq!(n, 42);

// Read a single string from input.
//
// v
// 42 abc def
let n: String = read!();
assert_eq!(n, "abc");

// Read a vector of characters from input.
// Spaces are ignored, and those characters need not be separated by spaces.
//
// v
// 42 abc def
let v: Vec<char> = read!();
assert_eq!(v, ['d', 'e', 'f']);

// Read a tuple from input.
// Equivalent to:
// Read a tuple from input. Equivalent to:
//
// ```
// let l: u32 = read!();
// let m: f64 = read!();
// let n: String = read!();
// ```
//
// v
// 0 0.3 lmn
let (l, m, n): (u32, f64, String) = read!();
assert_eq!(l, 0);
assert_eq!(m, 0.3);
assert_eq!(n, "lmn");

// Read a vector of integers from input.
// They are separated by spaces.
//
// v
// 1 2 3
let v: Vec<u32> = read!(3);
assert_eq!(v, [1, 2, 3]);

// Read a matrix of integers from input.
// They are separated by spaces, and newlines are unnecessary but useful for readability.
//
// v
// 1 2 3
// 4 5 6
let m: Mat<u32> = read!(2, 3);
assert_eq!(m, [[1, 2, 3], [4, 5, 6]]);

// Read a matrix of characters from input.
// Spaces are ignored and unnecessary, too.
//
// v
// .@/#$
// !@#!@
// *&@:,
let m: Mat<char> = read!(3, 5);
assert_eq!(
m,
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,8 @@ pub use {
formatted::SepBy,
mat::Mat,
read::{
error::ReadIntoError,
read_from::ReadFrom,
error::ReadError,
read_from::{ReadFrom, ReadFromError},
read_into::ReadInto,
read_one_from::{ReadOneFrom, ReadOneFromError},
read_one_into::ReadOneInto,
Expand Down
14 changes: 7 additions & 7 deletions src/read/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::stream::{self, MSG_EOF, MSG_EOL};
/// [ReadInto]: crate::ReadInto
/// [ReadOneFrom]: crate::ReadOneFrom
#[derive(Debug)]
pub enum ReadIntoError<E> {
pub enum ReadError<E> {
/// Error during reading from input.
IOError(std::io::Error),
/// Unexpected end of file.
Expand All @@ -20,7 +20,7 @@ pub enum ReadIntoError<E> {
FromStrError(E, String, &'static str),
}

impl<E> Display for ReadIntoError<E>
impl<E> Display for ReadError<E>
where
E: std::error::Error,
{
Expand All @@ -41,20 +41,20 @@ where
}
}

impl<E> std::error::Error for ReadIntoError<E> where E: std::error::Error {}
impl<E> std::error::Error for ReadError<E> where E: std::error::Error {}

impl<E> From<std::io::Error> for ReadIntoError<E> {
impl<E> From<std::io::Error> for ReadError<E> {
fn from(error: std::io::Error) -> Self {
Self::IOError(error)
}
}

impl<E> From<stream::error::StreamError> for ReadIntoError<E> {
impl<E> From<stream::error::StreamError> for ReadError<E> {
fn from(error: stream::error::StreamError) -> Self {
match error {
stream::error::StreamError::IOError(e) => Self::IOError(e),
stream::error::StreamError::EOF => Self::EOF,
stream::error::StreamError::EOL => Self::EOL,
stream::error::StreamError::Eof => Self::EOF,
stream::error::StreamError::Eol => Self::EOL,
}
}
}
6 changes: 3 additions & 3 deletions src/read/iter.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::read_one_from::ReadOneFromError;
use crate::{
stream::{error::StreamError, line_buf::LineBuf},
BufReadExt, ReadIntoError, ReadOneFrom,
BufReadExt, ReadError, ReadOneFrom,
};
use std::marker::PhantomData;

Expand All @@ -24,7 +24,7 @@ impl<'s, S: BufReadExt + ?Sized, T: ReadOneFrom> Iterator for ReadAll<'s, S, T>
fn next(&mut self) -> Option<Self::Item> {
match self.stream.try_get_string_some() {
Ok(s) => Some(T::parse(s)),
Err(StreamError::EOF | StreamError::EOL) => None,
Err(StreamError::Eof | StreamError::Eol) => None,
Err(e) => Some(Err(e.into())),
}
}
Expand All @@ -50,7 +50,7 @@ impl<'s, T: ReadOneFrom> Iterator for ReadAllIn<'s, T> {
fn next(&mut self) -> Option<Self::Item> {
match T::try_read_one_from(&mut self.stream) {
Ok(t) => Some(Ok(t)),
Err(ReadIntoError::EOF | ReadIntoError::EOL) => None,
Err(ReadError::EOF | ReadError::EOL) => None,
Err(e) => Some(Err(e)),
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/read/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ macro_rules! impl_read_into_single {
type ParseError = <char as ::std::str::FromStr>::Err;

fn parse(s: &str) -> Result<char, $crate::ReadOneFromError<Self>> {
s.parse().map_err(|err| $crate::ReadIntoError::FromStrError(err, s.to_owned(), ::std::any::type_name::<char>()))
s.parse().map_err(|err| $crate::ReadError::FromStrError(err, s.to_owned(), ::std::any::type_name::<char>()))
}

fn try_read_one_from<S: $crate::BufReadExt>(stream: &mut S) -> Result<char, $crate::ReadOneFromError<Self>> {
Expand All @@ -52,7 +52,7 @@ macro_rules! impl_read_into_single {
type ParseError = <$ty as ::std::str::FromStr>::Err;

fn parse(s: &str) -> Result<$ty, $crate::ReadOneFromError<Self>> {
s.parse().map_err(|err| $crate::ReadIntoError::FromStrError(err, s.to_owned(), ::std::any::type_name::<$ty>()))
s.parse().map_err(|err| $crate::ReadError::FromStrError(err, s.to_owned(), ::std::any::type_name::<$ty>()))
}
}
$crate::impl_read_into_single!($($tys)*);
Expand Down
16 changes: 8 additions & 8 deletions src/read/read_from.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
use super::read_one_from::ReadOneFrom;
use crate::{array::array_try_from_fn, mat::Mat, BufReadExt, ReadIntoError};
use crate::{array::array_try_from_fn, mat::Mat, BufReadExt, ReadError};
use std::fmt::{self, Display};

/// The error type for [ReadFrom].
pub type ReadFromError<T> = ReadIntoError<<T as ReadFrom>::ParseError>;
pub type ReadFromError<T> = ReadError<<T as ReadFrom>::ParseError>;

/// Read data from input stream.
///
/// # Errors
///
/// - If the input cannot be parsed into `T`, [ReadIntoError::FromStrError] is returned.
/// - If the input is not valid UTF-8, [ReadIntoError::IOError] is returned.
/// - If an I/O error occurs, [ReadIntoError::IOError] is returned.
/// - If the input cannot be parsed into `T`, [ReadError::FromStrError] is returned.
/// - If the input is not valid UTF-8, [ReadError::IOError] is returned.
/// - If an I/O error occurs, [ReadError::IOError] is returned.
///
/// [ReadIntoError]: crate::ReadIntoError
/// [ReadIntoError::FromStrError]: crate::ReadIntoError::FromStrError
/// [ReadIntoError::IOError]: crate::ReadIntoError::IOError
/// [ReadError]: crate::ReadError
/// [ReadError::FromStrError]: crate::ReadError::FromStrError
/// [ReadError::IOError]: crate::ReadError::IOError
pub trait ReadFrom: Sized {
/// Errors that come from [ReadOneFrom].
type ParseError: std::error::Error;
Expand Down
4 changes: 2 additions & 2 deletions src/read/read_into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ use super::read_from::ReadFromError;
pub trait ReadInto<T>: BufReadExt {
/// Errors that come from [ReadOneFrom].
///
/// This is usually [ReadIntoError].
/// This is usually [ReadError].
///
/// [ReadOneFrom]: crate::ReadOneFrom
/// [ReadIntoError]: crate::ReadIntoError
/// [ReadError]: crate::ReadError
type Error: std::error::Error;

/// Read from `self` and parse into `Self`.
Expand Down
32 changes: 16 additions & 16 deletions src/read/read_one_from.rs
Original file line number Diff line number Diff line change
@@ -1,80 +1,80 @@
use super::iter::{ReadAll, ReadAllIn};
use crate::{BufReadExt, ReadIntoError};
use crate::{BufReadExt, ReadError};

/// The error type for [ReadOneFrom].
pub type ReadOneFromError<T> = ReadIntoError<<T as ReadOneFrom>::ParseError>;
pub type ReadOneFromError<T> = ReadError<<T as ReadOneFrom>::ParseError>;

/// Read a single data item from input stream.
///
/// All types that implement this trait also implement [ReadFrom].
///
/// # Errors
///
/// - If the input cannot be parsed into `T`, [ReadIntoError::FromStrError] is returned.
/// - If the input is not valid UTF-8, [ReadIntoError::IOError] is returned.
/// - If an I/O error occurs, [ReadIntoError::IOError] is returned.
/// - If the input cannot be parsed into `T`, [ReadError::FromStrError] is returned.
/// - If the input is not valid UTF-8, [ReadError::IOError] is returned.
/// - If an I/O error occurs, [ReadError::IOError] is returned.
///
/// [ReadFrom]: crate::ReadFrom
/// [ReadIntoError]: crate::ReadIntoError
/// [ReadIntoError::FromStrError]: crate::ReadIntoError::FromStrError
/// [ReadIntoError::IOError]: crate::ReadIntoError::IOError
/// [ReadError]: crate::ReadError
/// [ReadError::FromStrError]: crate::ReadError::FromStrError
/// [ReadError::IOError]: crate::ReadError::IOError
pub trait ReadOneFrom: Sized {
/// Errors that come from parsing.
type ParseError: std::error::Error;

/// Parse a string into `Self`.
fn parse(s: &str) -> Result<Self, ReadIntoError<Self::ParseError>>;
fn parse(s: &str) -> Result<Self, ReadError<Self::ParseError>>;

/// Read from `stream` and parse into `Self`.
fn try_read_one_from<S: BufReadExt>(
stream: &mut S,
) -> Result<Self, ReadIntoError<Self::ParseError>> {
) -> Result<Self, ReadError<Self::ParseError>> {
let s = stream.try_get_string_some()?;
Self::parse(s)
}

/// Read an element in a single non-whitespace character from `stream`, parse into `Self`.
fn try_read_in_char_from<S: BufReadExt>(
stream: &mut S,
) -> Result<Self, ReadIntoError<Self::ParseError>> {
) -> Result<Self, ReadError<Self::ParseError>> {
let s = stream.try_get_non_ws()?;
Self::parse(s.encode_utf8(&mut [0; 4]))
}

/// Read an element in the remained line from `stream`, parse into `Self`.
fn try_read_in_line_trimmed_from<S: BufReadExt>(
stream: &mut S,
) -> Result<Self, ReadIntoError<Self::ParseError>> {
) -> Result<Self, ReadError<Self::ParseError>> {
let s = stream.try_get_line_trimmed()?.trim_start();
Self::parse(s)
}

/// Read an element in a single trimmed line that is not empty from `stream`, parse into `Self`.
fn try_read_in_line_some_trimmed_from<S: BufReadExt>(
stream: &mut S,
) -> Result<Self, ReadIntoError<Self::ParseError>> {
) -> Result<Self, ReadError<Self::ParseError>> {
let s = stream.try_get_line_some_trimmed()?.trim_start();
Self::parse(s)
}

/// Read all remaining elements from `stream` into a [Vec] of `Self`.
fn try_read_all_from<S: BufReadExt>(
stream: &mut S,
) -> Result<Vec<Self>, ReadIntoError<Self::ParseError>> {
) -> Result<Vec<Self>, ReadError<Self::ParseError>> {
ReadAll::<S, Self>::new(stream).collect()
}

/// Read all elements in current line from `stream` into a [Vec] of `Self`.
fn try_read_any_in_line_from<S: BufReadExt>(
stream: &mut S,
) -> Result<Vec<Self>, ReadIntoError<Self::ParseError>> {
) -> Result<Vec<Self>, ReadError<Self::ParseError>> {
ReadAllIn::<Self>::new(stream.try_get_line_trimmed()?).collect()
}

/// Read all elements in a non-empty line from `stream` into a [Vec] of `Self`.
fn try_read_some_in_line_from<S: BufReadExt>(
stream: &mut S,
) -> Result<Vec<Self>, ReadIntoError<Self::ParseError>> {
) -> Result<Vec<Self>, ReadError<Self::ParseError>> {
ReadAllIn::<Self>::new(stream.try_get_line_some_trimmed()?).collect()
}
}
4 changes: 2 additions & 2 deletions src/read/read_one_into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use crate::{stream, unwrap, BufReadExt, ReadOneFrom, ReadOneFromError};
pub trait ReadOneInto<T> {
/// Errors that come from [ReadOneFrom].
///
/// This is usually [ReadIntoError].
/// This is usually [ReadError].
///
/// [ReadIntoError]: crate::ReadIntoError
/// [ReadError]: crate::ReadError
type Error: std::error::Error + From<stream::error::StreamError>;

/// Read one from `self` and parse into `T`.
Expand Down
8 changes: 6 additions & 2 deletions src/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ pub(crate) mod stream;
pub static STDIN: LazyLock<Mutex<InputStream<BufReader<Stdin>>>> =
LazyLock::new(|| Mutex::new(InputStream::new(BufReader::new(io::stdin()))));

/// Get a handle to the standard input stream.
/// Get an exclusive handle to the standard input stream.
///
/// See [io::stdin] and [io::Stdin::lock] for more information.
pub fn stdin() -> MutexGuard<'static, InputStream<BufReader<Stdin>>> {
STDIN.lock().unwrap()
}

/// Get a handle to the standard output stream.
/// Get an exclusive handle to the standard output stream.
///
/// See [io::stdout] and [io::Stdout::lock] for more information.
pub fn stdout() -> io::StdoutLock<'static> {
io::stdout().lock()
}
Loading

0 comments on commit 0e6348a

Please sign in to comment.