Skip to content

Commit

Permalink
release: 0.1.3
Browse files Browse the repository at this point in the history
  • Loading branch information
joshstoik1 committed May 31, 2022
2 parents 9fd1982 + 8e0aedb commit c9878b6
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 101 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog



## [0.1.3](https://github.com/Blobfolio/trimothy/releases/tag/v0.1.3) - 2022-05-30

### Changed

* Minor performance improvements for `TrimSlice` implementations



## [0.1.2](https://github.com/Blobfolio/trimothy/releases/tag/v0.1.2) - 2022-04-30

### 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.2
Generated: 2022-04-30 19:39:20 UTC
Version: 0.1.3
Generated: 2022-05-31 02:54:49 UTC

This package has no dependencies.
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "trimothy"
version = "0.1.2"
version = "0.1.3"
authors = ["Blobfolio, LLC. <[email protected]>"]
edition = "2021"
rust-version = "1.60"
Expand All @@ -25,12 +25,12 @@ man-dir = "./"
credits-dir = "./"

[dev-dependencies]
brunch = "0.2.*"
brunch = "0.2.*, >=0.2.5"

[[bench]]
name = "fn_trim_slice"
harness = false

[[bench]]
name = "fn_trim_mut_vec"
name = "fn_trim_mut"
harness = false
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
[![crates.io](https://img.shields.io/crates/v/trimothy.svg)](https://crates.io/crates/trimothy)
[![Build Status](https://github.com/Blobfolio/trimothy/workflows/Build/badge.svg)](https://github.com/Blobfolio/trimothy/actions)
[![Dependency Status](https://deps.rs/repo/github/blobfolio/trimothy/status.svg)](https://deps.rs/repo/github/blobfolio/trimothy)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/Blobfolio/trimothy)

Trimothy is a small library that expands on the limited String- and slice-trimming capabilities provided by the standard library.

Expand Down
File renamed without changes.
15 changes: 14 additions & 1 deletion benches/fn_trim_slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use brunch::{
Bench,
benches,
};
use trimothy::TrimSlice;
use trimothy::{
TrimSlice,
TrimSliceMatches,
};
use std::time::Duration;


Expand Down Expand Up @@ -44,4 +47,14 @@ benches!(
Bench::new("&str", "trim_end()")
.timed(Duration::from_secs(1))
.with(|| STR.trim_end()),

Bench::spacer(),

Bench::new("&[u8]", "trim_start_matches()")
.timed(Duration::from_secs(1))
.with(|| BYTES.trim_start_matches(|b| matches!(b, b'\t' | b' ' | b'\n' | b'H' | b'e'))),

Bench::new("&str", "trim_start_matches()")
.timed(Duration::from_secs(1))
.with(|| STR.trim_start_matches(|c| matches!(c, '\t' | ' ' | '\n' | 'H' | 'e'))),
);
103 changes: 29 additions & 74 deletions src/trim_mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,31 @@ pub trait TrimMatchesMut {



/// # Helper: String Trim.
macro_rules! string_trim {
($lhs:ident, $trimmed:expr) => (
let trimmed = $trimmed;
let trimmed_len = trimmed.len();

if trimmed_len < $lhs.len() {
if 0 < trimmed_len {
let trimmed_ptr = trimmed.as_ptr();

// Safety: we're just moving the trimmed portion to the start
// of the buffer and chopping the length to match.
unsafe {
let v = $lhs.as_mut_vec();
copy(trimmed_ptr, v.as_mut_ptr(), trimmed_len);
v.set_len(trimmed_len);
}
}
else { $lhs.truncate(0); }
}
);
}



impl TrimMut for String {
#[allow(unsafe_code)]
/// # Trim Mut.
Expand All @@ -123,25 +148,7 @@ impl TrimMut for String {
/// s.trim_mut();
/// assert_eq!(s, "Hello World!");
/// ```
fn trim_mut(&mut self) {
let trimmed = self.trim();
let trimmed_len = trimmed.len();

if trimmed_len < self.len() {
if 0 < trimmed_len {
let trimmed_ptr = trimmed.as_ptr();

// Safety: we're just moving the trimmed portion to the start
// of the buffer and chopping the length to match.
unsafe {
let v = self.as_mut_vec();
copy(trimmed_ptr, v.as_mut_ptr(), trimmed_len);
v.set_len(trimmed_len);
}
}
else { self.truncate(0); }
}
}
fn trim_mut(&mut self) { string_trim!(self, self.trim()); }

#[allow(unsafe_code)]
/// # Trim Start Mut.
Expand All @@ -157,25 +164,7 @@ impl TrimMut for String {
/// s.trim_start_mut();
/// assert_eq!(s, "Hello World! ");
/// ```
fn trim_start_mut(&mut self) {
let trimmed = self.trim_start();
let trimmed_len = trimmed.len();

if trimmed_len < self.len() {
if 0 < trimmed_len {
let trimmed_ptr = trimmed.as_ptr();

// Safety: we're just moving the trimmed portion to the start
// of the buffer and chopping the length to match.
unsafe {
let v = self.as_mut_vec();
copy(trimmed_ptr, v.as_mut_ptr(), trimmed_len);
v.set_len(trimmed_len);
}
}
else { self.truncate(0); }
}
}
fn trim_start_mut(&mut self) { string_trim!(self, self.trim_start()); }

/// # Trim End Mut.
///
Expand Down Expand Up @@ -217,25 +206,7 @@ impl TrimMatchesMut for String {
/// assert_eq!(s, "ello World!");
/// ```
fn trim_matches_mut<F>(&mut self, cb: F)
where F: Fn(Self::MatchUnit) -> bool {
let trimmed = self.trim_matches(cb);
let trimmed_len = trimmed.len();

if trimmed_len < self.len() {
if 0 < trimmed_len {
let trimmed_ptr = trimmed.as_ptr();

// Safety: we're just moving the trimmed portion to the start
// of the buffer and chopping the length to match.
unsafe {
let v = self.as_mut_vec();
copy(trimmed_ptr, v.as_mut_ptr(), trimmed_len);
v.set_len(trimmed_len);
}
}
else { self.truncate(0); }
}
}
where F: Fn(Self::MatchUnit) -> bool { string_trim!(self, self.trim_matches(cb)); }

#[allow(unsafe_code)]
/// # Trim Start Matches Mut.
Expand All @@ -255,23 +226,7 @@ impl TrimMatchesMut for String {
/// ```
fn trim_start_matches_mut<F>(&mut self, cb: F)
where F: Fn(Self::MatchUnit) -> bool {
let trimmed = self.trim_start_matches(cb);
let trimmed_len = trimmed.len();

if trimmed_len < self.len() {
if 0 < trimmed_len {
let trimmed_ptr = trimmed.as_ptr();

// Safety: we're just moving the trimmed portion to the start
// of the buffer and chopping the length to match.
unsafe {
let v = self.as_mut_vec();
copy(trimmed_ptr, v.as_mut_ptr(), trimmed_len);
v.set_len(trimmed_len);
}
}
else { self.truncate(0); }
}
string_trim!(self, self.trim_start_matches(cb));
}

/// # Trim End Matches Mut.
Expand Down
57 changes: 36 additions & 21 deletions src/trim_slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use alloc::{
boxed::Box,
vec::Vec,
};
use crate::not_whitespace;



Expand Down Expand Up @@ -136,33 +135,19 @@ macro_rules! trim_slice {
/// # Trim.
///
/// Trim leading and trailing (ASCII) whitespace from a slice.
fn trim(&self) -> &[u8] {
self.iter()
.position(not_whitespace)
.map_or(&[], |start| {
// We know there is an end because there's a beginning.
let end = self.iter().rposition(not_whitespace).unwrap();
&self[start..=end]
})
}
fn trim(&self) -> &[u8] { trim_end(trim_start(&self)) }

#[inline]
/// # Trim Start.
///
/// Trim leading (ASCII) whitespace from a slice.
fn trim_start(&self) -> &[u8] {
self.iter()
.position(not_whitespace)
.map_or(&[], |p| &self[p..])
}
fn trim_start(&self) -> &[u8] { trim_start(&self) }

#[inline]
/// # Trim End.
///
/// Trim trailing (ASCII) whitespace from a slice.
fn trim_end(&self) -> &[u8] {
self.iter()
.rposition(not_whitespace)
.map_or(&[], |p| &self[..=p])
}
fn trim_end(&self) -> &[u8] { trim_end(&self) }
}

impl TrimSliceMatches for $ty {
Expand Down Expand Up @@ -208,7 +193,33 @@ macro_rules! trim_slice {
)+);
}

trim_slice!(&[u8], Box<[u8]>, Vec<u8>);
trim_slice!([u8], Box<[u8]>, Vec<u8>);



/// # Trim Slice Start.
///
/// This is a copy of the nightly `trim_ascii_start` so it can be used on
/// stable. If/when that feature is stabilized, we'll use it directly.
const fn trim_start(mut src: &[u8]) -> &[u8] {
while let [first, rest @ ..] = src {
if first.is_ascii_whitespace() { src = rest; }
else { break; }
}
src
}

/// # Trim Slice End.
///
/// This is a copy of the nightly `trim_ascii_end` so it can be used on
/// stable. If/when that feature is stabilized, we'll use it directly.
const fn trim_end(mut src: &[u8]) -> &[u8] {
while let [rest @ .., last] = src {
if last.is_ascii_whitespace() { src = rest; }
else { break; }
}
src
}



Expand Down Expand Up @@ -255,6 +266,10 @@ mod tests {
assert_eq!(T_HELLO_E.trim_matches(|b| b'h' == b), b"ello\t");
assert_eq!(T_HELLO_E.to_vec().trim_matches(|b| b'h' == b), b"ello\t");
assert_eq!(Box::<[u8]>::from(T_HELLO_E).trim_matches(|b| b'h' == b), b"ello\t");

// This should also work on arrays.
let arr: [u8; 5] = [b' ', b' ', b'.', b' ', b' '];
assert_eq!(arr.trim(), &[b'.']);
}

#[test]
Expand Down

0 comments on commit c9878b6

Please sign in to comment.