Skip to content

Commit

Permalink
Rename locale to format to avoid confusion and update documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
TheVeryDarkness committed Oct 14, 2024
1 parent f2e28da commit acd98d0
Show file tree
Hide file tree
Showing 23 changed files with 377 additions and 331 deletions.
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ pub use {
mat::Mat,
read::{
error::ReadError,
locale,
fmt,
read_from::{ReadFrom, ReadFromError},
read_into::ReadInto,
read_one_from::{ReadOneFrom, ReadOneFromError},
Expand Down
137 changes: 137 additions & 0 deletions src/read/fmt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
//! [Format] trait for input format and built-in formats.
use crate::{
stream::{COMMA, CR, HT, LF, SP},
utf8char::FixedUtf8Char,
};

/// Trait for input format.
pub trait Format<Char = char> {
/// Get the list of whitespace characters.
fn skipped_chars(&self) -> &[Char];
}

impl<L: Format<Char> + ?Sized, Char> Format<Char> for &L {
#[inline]
fn skipped_chars(&self) -> &[Char] {
<L as Format<Char>>::skipped_chars(self)
}
}

/// Default Format.
///
/// Whitespace characters here are `' '`, `'\t'`, `'\n'`, and `'\r'`.
pub struct Default;

const WHITE_SPACES: [FixedUtf8Char; 4] = [SP, HT, LF, CR];

impl Format<FixedUtf8Char> for Default {
#[inline]
fn skipped_chars(&self) -> &[FixedUtf8Char] {
&WHITE_SPACES
}
}

impl Format<char> for Default {
#[inline]
fn skipped_chars(&self) -> &[char] {
&[' ', '\t', '\n', '\r']
}
}

/// Format for CSV.
///
/// Whitespace characters here are `' '`, `'\t'`, `','`, `'\n'`, and `'\r'`.
pub struct CSV;

const CSV_SEP: [FixedUtf8Char; 5] = [SP, HT, COMMA, LF, CR];

impl Format<FixedUtf8Char> for CSV {
#[inline]
fn skipped_chars(&self) -> &[FixedUtf8Char] {
&CSV_SEP
}
}

impl Format<char> for CSV {
#[inline]
fn skipped_chars(&self) -> &[char] {
&[' ', '\t', ',', '\n', '\r']
}
}

/// Special format that skip the given characters.
pub struct Skip<Char = char>(Vec<Char>);

impl<Char: From<C> + Ord, C> FromIterator<C> for Skip<Char> {
#[inline]
fn from_iter<T: IntoIterator<Item = C>>(iter: T) -> Self {
let mut v: Vec<_> = iter.into_iter().map(From::from).collect();
v.sort();
v.dedup();
Self(v)
}
}

impl Format<FixedUtf8Char> for Skip<FixedUtf8Char> {
#[inline]
fn skipped_chars(&self) -> &[FixedUtf8Char] {
&self.0
}
}

impl Format<char> for Skip<char> {
#[inline]
fn skipped_chars(&self) -> &[char] {
&self.0
}
}

/// Create a [Format] instance that skip the given characters.
#[inline]
pub fn skip<Char: Ord, T: IntoIterator<Item = Char>>(iter: T) -> Skip<Char> {
iter.into_iter().collect()
}

#[cfg(test)]
mod tests {
use super::Default;
use crate::{
fmt::{Format, Skip, CSV, WHITE_SPACES},
utf8char::FixedUtf8Char,
};

#[test]
fn equivalence() {
assert_eq!(
<Default as Format<char>>::skipped_chars(&Default),
<Default as Format<FixedUtf8Char>>::skipped_chars(&Default),
);
assert_eq!(
<&Default as Format<char>>::skipped_chars(&&Default),
<&Default as Format<FixedUtf8Char>>::skipped_chars(&&Default),
);
assert_eq!(
<CSV as Format<char>>::skipped_chars(&CSV),
<CSV as Format<FixedUtf8Char>>::skipped_chars(&CSV),
);
assert_eq!(
<&CSV as Format<char>>::skipped_chars(&&CSV),
<&CSV as Format<FixedUtf8Char>>::skipped_chars(&&CSV),
);

let seps = [' ', '\t', '\n', '\r'];
assert_eq!(
<Skip<char> as Format<char>>::skipped_chars(&FromIterator::from_iter(seps)),
<Skip<FixedUtf8Char> as Format<FixedUtf8Char>>::skipped_chars(
&FromIterator::from_iter(seps)
),
);
assert_eq!(
<Skip<char> as Format<char>>::skipped_chars(&FromIterator::from_iter(WHITE_SPACES)),
<Skip<FixedUtf8Char> as Format<FixedUtf8Char>>::skipped_chars(
&FromIterator::from_iter(WHITE_SPACES)
),
);
}
}
8 changes: 4 additions & 4 deletions src/read/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
};
use std::{ffi::OsString, net::*, num::*, path::PathBuf};

use super::locale;
use super::fmt;

// Implement `Parse` for all types that implement FromStr.
impl_read_one_from_for_from_str!(
Expand Down Expand Up @@ -45,10 +45,10 @@ impl ReadOneFrom for char {
}

#[inline]
fn try_read_one_from<L: locale::Locale, S: BufReadExt>(
fn try_read_one_from<F: fmt::Format, S: BufReadExt>(
stream: &mut S,
locale: &L,
format: &F,
) -> Result<char, ReadOneFromError<Self>> {
<Self as ReadOneFrom>::try_read_in_char_from(stream, locale)
<Self as ReadOneFrom>::try_read_in_char_from(stream, format)
}
}
45 changes: 21 additions & 24 deletions src/read/iter.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,38 @@
use super::read_one_from::ReadOneFromError;
use crate::{
locale::Locale,
fmt::Format,
stream::{error::StreamError, line_buf::LineBuf},
BufReadExt, ReadError, ReadOneFrom,
};
use std::marker::PhantomData;

/// Iterator for all elements.
pub(super) struct ReadAll<'l, 's, L: Locale, S: ?Sized, T: ReadOneFrom> {
locale: &'l L,
pub(super) struct ReadAll<'f, 's, F: Format, S: ?Sized, T: ReadOneFrom> {
format: &'f F,
stream: &'s mut S,
phantom: PhantomData<T>,
}

impl<'l, 's, L: Locale, S: ?Sized, T: ReadOneFrom> ReadAll<'l, 's, L, S, T> {
impl<'f, 's, F: Format, S: ?Sized, T: ReadOneFrom> ReadAll<'f, 's, F, S, T> {
#[inline]
pub(crate) fn new(stream: &'s mut S, locale: &'l L) -> Self {
pub(crate) fn new(stream: &'s mut S, format: &'f F) -> Self {
let phantom = PhantomData;
Self {
locale,
format,
stream,
phantom,
}
}
}

impl<'l, 's, L: Locale, S: BufReadExt + ?Sized, T: ReadOneFrom> Iterator
for ReadAll<'l, 's, L, S, T>
impl<'l, 's, F: Format, S: BufReadExt + ?Sized, T: ReadOneFrom> Iterator
for ReadAll<'l, 's, F, S, T>
{
type Item = Result<T, ReadOneFromError<T>>;

#[inline]
fn next(&mut self) -> Option<Self::Item> {
match self
.stream
.try_get_string_some(self.locale.whitespace_chars())
{
match self.stream.try_get_string_some(self.format.skipped_chars()) {
Ok(s) => Some(T::parse(s)),
Err(StreamError::Eof | StreamError::Eol) => None,
Err(e) => Some(Err(e.into())),
Expand All @@ -44,31 +41,31 @@ impl<'l, 's, L: Locale, S: BufReadExt + ?Sized, T: ReadOneFrom> Iterator
}

/// Iterator for all elements in a string.
pub(super) struct ReadAllIn<'l, 's, L: Locale, T: ReadOneFrom> {
locale: &'l L,
pub(super) struct ReadAllIn<'f, 's, F: Format, T: ReadOneFrom> {
format: &'f F,
stream: LineBuf<'s>,
phantom: PhantomData<T>,
}

impl<'l, 's, L: Locale, T: ReadOneFrom> ReadAllIn<'l, 's, L, T> {
impl<'l, 's, L: Format, T: ReadOneFrom> ReadAllIn<'l, 's, L, T> {
#[inline]
pub(crate) fn new(buffer: &'s str, locale: &'l L) -> Self {
pub(crate) fn new(buffer: &'s str, format: &'l L) -> Self {
let stream = LineBuf::new(buffer);
let phantom = PhantomData;
Self {
locale,
format,
stream,
phantom,
}
}
}

impl<'l, 's, L: Locale, T: ReadOneFrom> Iterator for ReadAllIn<'l, 's, L, T> {
impl<'l, 's, L: Format, T: ReadOneFrom> Iterator for ReadAllIn<'l, 's, L, T> {
type Item = Result<T, ReadOneFromError<T>>;

#[inline]
fn next(&mut self) -> Option<Self::Item> {
match T::try_read_one_from(&mut self.stream, self.locale) {
match T::try_read_one_from(&mut self.stream, self.format) {
Ok(t) => Some(Ok(t)),
Err(ReadError::EOF | ReadError::EOL) => None,
Err(e) => Some(Err(e)),
Expand All @@ -80,7 +77,7 @@ impl<'l, 's, L: Locale, T: ReadOneFrom> Iterator for ReadAllIn<'l, 's, L, T> {
mod tests {
use super::ReadAll;
use crate::{
locale::{Locale, ASCII},
fmt::{Default, Format},
stream::line_buf::LineBuf,
unwrap, BufReadExt, InputStream, ReadInto,
};
Expand All @@ -90,7 +87,7 @@ mod tests {
fn line_buf_strings() {
let s = "Hello, world!";
let mut buf = LineBuf::new(s);
let iter = ReadAll::new(&mut buf, &ASCII);
let iter = ReadAll::new(&mut buf, &Default);
let res: Result<Vec<String>, _> = iter.collect();
let res = unwrap!(res);
assert_eq!(res, vec!["Hello,", "world!"]);
Expand All @@ -100,7 +97,7 @@ mod tests {
fn input_stream_strings() {
let s = "Hello, world!";
let mut buf = InputStream::new(Cursor::new(s));
let iter = ReadAll::new(&mut buf, &ASCII);
let iter = ReadAll::new(&mut buf, &Default);
let res: Result<Vec<String>, _> = iter.collect();
let res = unwrap!(res);
assert_eq!(res, vec!["Hello,", "world!"]);
Expand All @@ -111,15 +108,15 @@ mod tests {
fn line_buf_string() {
let s = "\n";
let mut buf = LineBuf::new(s);
let _: &str = unwrap!(buf.try_get_string_some(ASCII.whitespace_chars()));
let _: &str = unwrap!(buf.try_get_string_some(Default.skipped_chars()));
}

#[test]
#[should_panic = "expect more characters before EOF"]
fn input_stream_string() {
let s = "\n";
let mut buf = InputStream::new(Cursor::new(s));
let _: &str = unwrap!(buf.try_get_string_some(ASCII.whitespace_chars()));
let _: &str = unwrap!(buf.try_get_string_some(Default.skipped_chars()));
}

#[test]
Expand Down
Loading

0 comments on commit acd98d0

Please sign in to comment.