Skip to content

Commit

Permalink
Add string slicing by character #52
Browse files Browse the repository at this point in the history
  • Loading branch information
mverleg committed Jun 1, 2018
1 parent d3a555b commit a60d144
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/mango/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ pub mod collection;

pub mod strtype;

pub mod strslice;

pub mod numtype;

pub mod signaltype;
Expand Down
4 changes: 4 additions & 0 deletions src/mango/util/strslice/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub mod slice;
pub use self::slice::charslice;
pub use self::slice::charslicefrom;
pub use self::slice::charsliceto;
64 changes: 64 additions & 0 deletions src/mango/util/strslice/slice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/// Take a character-based slice of a string (as opposed to the default byte-slice).
/// Allows negative indices to slice from the end (but start must be before end).
/// This may not be very fast.
pub fn charslice<S: Into<String>>(text: S, start: isize, end: isize) -> String {
let stext = text.into();
let from: usize;
let length: usize;
if start < 0 {
// LATER: may remove this check and just default to 0 in the future.
assert!(
-start as usize <= stext.len(),
"charslice: if 'start' is negative, the magnitude may not exceed the length"
);
// TODO: off by one?
from = (stext.len() as isize + start) as usize;
} else {
from = start as usize;
}
if end < 0 {
// LATER: may remove this check and just default to 0 in the future.
assert!(
-end as usize <= stext.len(),
"charslice: if 'end' is negative, the magnitude may not exceed the length"
);
// TODO: off by one?
let new_end = (stext.len() as isize + end) as usize;
assert!(
new_end >= from,
"charslice: 'start' may not be before 'end' (end was positive)"
);
length = new_end - from;
} else {
assert!(
end >= from as isize,
"charslice: 'start' may not be before 'end' (end was positive)"
);
length = end as usize - from;
}
stext.chars().skip(from).take(length).collect()
}

pub fn charslicefrom<S: Into<String>>(text: S, start: isize) -> String {
let stext = text.into();
let len = stext.len() as isize;
charslice(stext, start, len)
}

pub fn charsliceto<S: Into<String>>(text: S, end: isize) -> String {
charslice(text, 0, end)
}

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

#[test]
fn test_slice() {
assert_eq!(42isize as usize, 42usize);
assert_eq!("你好", charslice("你好!", 0, 2));
assert_eq!("!", charslicefrom("你好!", 2));
assert_eq!("你好", charsliceto("你好!", 2));
// TODO: test negative values
}
}

0 comments on commit a60d144

Please sign in to comment.