Skip to content

Commit

Permalink
release: 0.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
joshstoik1 committed Oct 4, 2023
2 parents 76fa4d4 + a4a85b6 commit 0b64e23
Show file tree
Hide file tree
Showing 7 changed files with 206 additions and 10 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# Changelog


## [0.2.0](https://github.com/Blobfolio/trimothy/releases/tag/v0.2.0) - 2023-10-03

### New

* `NormalizeWhitespace` trait



## [0.1.8](https://github.com/Blobfolio/trimothy/releases/tag/v0.1.8) - 2023-06-01

### Changed
Expand Down
4 changes: 2 additions & 2 deletions CREDITS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Project Dependencies
Package: trimothy
Version: 0.1.7
Generated: 2023-06-01 20:20:18 UTC
Version: 0.2.0
Generated: 2023-10-04 04:34:44 UTC

This package has no dependencies.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "trimothy"
version = "0.1.8"
version = "0.2.0"
authors = ["Blobfolio, LLC. <[email protected]>"]
edition = "2021"
rust-version = "1.56"
Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,23 @@ This trait brings _mutable_ match-based trimming `String`, `Vec<u8>`, and `Box<[
| `trim_end_matches_mut` | Trim arbitrary trailing bytes via callback (mutably). |


### [`NormalizeWhitespace`]

This trait exposes an iterator over byte/string slice contents with the edges trimmed, and all contiguous inner whitespace converted to a single horizontal space.

| Method | Description |
| ------ | ----------- |
| `normalized_whitespace` | Return said iterator. |



## Installation

The dependency can be added the normal way:

```toml
[dependencies]
trimothy = "0.1"
trimothy = "0.2"
```


Expand Down
136 changes: 136 additions & 0 deletions src/iter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*!
# Trimothy - Normalized Whitespace Iterator
*/

use core::{
iter::Iterator,
slice::Iter,
str::Chars,
};
use crate::TrimSlice;



/// # Normalized Whitespace Iterator.
///
/// This trait adds a `normalized_whitespace` method to byte and string slices
/// for iterating over their contents with the edges trimmed, and all
/// contiguous inner whitespace converted to a single horizontal space.
pub trait NormalizeWhitespace<T> {
/// # Normalized Whitespace Iterator.
///
/// Return an iterator over the byte/char contents with the edges trimmed,
/// and all contiguous inner whitespace converted to a single horizontal
/// space.
fn normalized_whitespace(&self) -> NormalizedWhitespace<T>;
}

impl<'a> NormalizeWhitespace<Iter<'a, u8>> for &'a [u8] {
/// # Normalized Whitespace Iterator.
///
/// Return an iterator over the byte/char contents with the edges trimmed,
/// and all contiguous inner whitespace converted to a single horizontal
/// space.
///
/// ## Examples
///
/// ```
/// use trimothy::NormalizeWhitespace;
///
/// let abnormal: &[u8] = b" Hello World!\n";
/// let normal: Vec<u8> = abnormal.normalized_whitespace().collect();
/// assert_eq!(normal, b"Hello World!");
/// ```
fn normalized_whitespace(&self) -> NormalizedWhitespace<Iter<'a, u8>> {
NormalizedWhitespace {
iter: self.trim().iter(),
ws: false,
}
}
}

impl<'a> NormalizeWhitespace<Chars<'a>> for &'a str {
/// # Normalized Whitespace Iterator.
///
/// Return an iterator over the byte/char contents with the edges trimmed,
/// and all contiguous inner whitespace converted to a single horizontal
/// space.
///
/// ## Examples
///
/// ```
/// use trimothy::NormalizeWhitespace;
///
/// let abnormal: &str = " Hello World!\n";
/// let normal: String = abnormal.normalized_whitespace().collect();
/// assert_eq!(normal, "Hello World!");
/// ```
fn normalized_whitespace(&self) -> NormalizedWhitespace<Chars<'a>> {
NormalizedWhitespace {
iter: self.trim().chars(),
ws: false,
}
}
}



#[derive(Debug)]
/// # (Actual) Normalized Whitespace Iterator.
///
/// This is the actual iterator returned by a
/// `NormalizeWhitespace::normalized_whitespace` implementation.
pub struct NormalizedWhitespace<T> {
iter: T,
ws: bool
}

impl<'a> Iterator for NormalizedWhitespace<Iter<'a, u8>> {
type Item = u8;

fn next(&mut self) -> Option<Self::Item> {
loop {
let next = self.iter.next()?;
if next.is_ascii_whitespace() {
if ! self.ws {
self.ws = true;
return Some(b' ');
}
}
else {
self.ws = false;
return Some(*next);
}
}
}

fn size_hint(&self) -> (usize, Option<usize>) {
let upper = self.iter.len();
(0, Some(upper))
}
}

impl<'a> Iterator for NormalizedWhitespace<Chars<'a>> {
type Item = char;

fn next(&mut self) -> Option<Self::Item> {
loop {
let next = self.iter.next()?;
if next.is_whitespace() {
if ! self.ws {
self.ws = true;
return Some(' ');
}
}
else {
self.ws = false;
return Some(next);
}
}
}

fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper)
}
}
13 changes: 7 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,13 @@ This trait brings _mutable_ match-based trimming `String`, `Vec<u8>`, and `Box<[
## Installation
### [`NormalizeWhitespace`]
The dependency can be added the normal way:
This trait exposes an iterator over byte/string slice contents with the edges trimmed, and all contiguous inner whitespace converted to a single horizontal space.
```ignore,toml
[dependencies]
trimothy = "0.1"
```
| Method | Description |
| ------ | ----------- |
| `normalized_whitespace` | Return said iterator. |
*/

#![forbid(unsafe_code)]
Expand Down Expand Up @@ -101,9 +100,11 @@ trimothy = "0.1"

extern crate alloc;

mod iter;
mod trim_mut;
mod trim_slice;

pub use iter::NormalizeWhitespace;
pub use trim_mut::{
TrimMut,
TrimMatchesMut,
Expand Down
42 changes: 42 additions & 0 deletions src/trim_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,3 +500,45 @@ impl TrimMatchesMut for Vec<u8> {
else { self.truncate(0); }
}
}



#[cfg(test)]
mod tests {
use super::*;

#[test]
fn trim_str() {
use alloc::borrow::ToOwned;

for v in [
"ĤéĹlo the WŎrld\u{0300}",
" ĤéĹlo the WŎrld\u{0300}",
" \tĤéĹlo the WŎrld\u{0300}",
"\r \nĤéĹlo\nthe WŎrld\u{0300}",
" ĤéĹlo the WŎrld\u{0300}\u{2003} ",
" \tĤéĹlo the WŎrld\u{0300} ",
"\r \nĤéĹlo\nthe WŎrld\u{0300} \t\t",
"ĤéĹlo the WŎrld\u{0300}\0 ",
"ĤéĹlo the WŎrld\u{0300}\r\r",
"ĤéĹlo the WŎrld\u{0300} \r\t",
"\nHello\nWorld\n!\n",
] {
let mut v2 = v.to_owned();
v2.trim_start_mut();
assert_eq!(v2, v.trim_start());

v2 = v.to_owned();
v2.trim_end_mut();
assert_eq!(v2, v.trim_end());

v2 = v.to_owned();
v2.trim_mut();
assert_eq!(v2, v.trim());

v2 = v.to_owned();
v2.trim_matches_mut(|c| c == '\t');
assert_eq!(v2, v.trim_matches(|c| c == '\t'));
}
}
}

0 comments on commit 0b64e23

Please sign in to comment.