mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-29 06:13:20 +00:00
Add a widestring split() function
This allows splitting widestrings about a char, similar to C++ split_string.
This commit is contained in:
parent
621a3a6a8b
commit
eecc796b04
1 changed files with 54 additions and 1 deletions
|
@ -158,6 +158,30 @@ where
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Iterator type for splitting a wide string on a char.
|
||||||
|
pub struct WStrCharSplitIter<'a> {
|
||||||
|
split: char,
|
||||||
|
chars: &'a [char],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for WStrCharSplitIter<'a> {
|
||||||
|
type Item = &'a wstr;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.chars.is_empty() {
|
||||||
|
return None;
|
||||||
|
} else if let Some(idx) = self.chars.iter().position(|c| *c == self.split) {
|
||||||
|
let (prefix, rest) = self.chars.split_at(idx);
|
||||||
|
self.chars = &rest[1..];
|
||||||
|
return Some(wstr::from_char_slice(prefix));
|
||||||
|
} else {
|
||||||
|
let res = self.chars;
|
||||||
|
self.chars = &[];
|
||||||
|
return Some(wstr::from_char_slice(res));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Convenience functions for WString.
|
/// Convenience functions for WString.
|
||||||
pub trait WExt {
|
pub trait WExt {
|
||||||
/// Access the chars of a WString or wstr.
|
/// Access the chars of a WString or wstr.
|
||||||
|
@ -182,6 +206,17 @@ pub trait WExt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \return an iterator over substrings, split by a given char.
|
||||||
|
/// The split char is not included in the substrings.
|
||||||
|
/// If the string is empty, the iterator will return no strings.
|
||||||
|
/// Note this differs from std::slice::split, which return a single empty item.
|
||||||
|
fn split(&self, c: char) -> WStrCharSplitIter {
|
||||||
|
WStrCharSplitIter {
|
||||||
|
split: c,
|
||||||
|
chars: self.as_char_slice(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// \return the index of the first occurrence of the given char, or None.
|
/// \return the index of the first occurrence of the given char, or None.
|
||||||
fn find_char(&self, c: char) -> Option<usize> {
|
fn find_char(&self, c: char) -> Option<usize> {
|
||||||
self.as_char_slice().iter().position(|&x| x == c)
|
self.as_char_slice().iter().position(|&x| x == c)
|
||||||
|
@ -218,7 +253,7 @@ impl WExt for wstr {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::WExt;
|
use super::WExt;
|
||||||
use crate::wchar::{WString, L};
|
use crate::wchar::{wstr, WString, L};
|
||||||
/// Write some tests.
|
/// Write some tests.
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn test_find_char() {
|
fn test_find_char() {
|
||||||
|
@ -247,4 +282,22 @@ mod tests {
|
||||||
assert!(L!("abc").ends_with(L!("bc")));
|
assert!(L!("abc").ends_with(L!("bc")));
|
||||||
assert!(L!("abc").ends_with(&WString::from_str("abc")));
|
assert!(L!("abc").ends_with(&WString::from_str("abc")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_split() {
|
||||||
|
fn do_split(s: &wstr, c: char) -> Vec<&wstr> {
|
||||||
|
s.split(c).collect()
|
||||||
|
}
|
||||||
|
assert_eq!(do_split(L!("abc"), 'b'), &["a", "c"]);
|
||||||
|
assert_eq!(do_split(L!("xxb"), 'x'), &["", "", "b"]);
|
||||||
|
assert_eq!(do_split(L!("bxxxb"), 'x'), &["b", "", "", "b"]);
|
||||||
|
assert_eq!(do_split(L!(""), 'x'), &[] as &[&str]);
|
||||||
|
assert_eq!(do_split(L!("foo,bar,baz"), ','), &["foo", "bar", "baz"]);
|
||||||
|
assert_eq!(do_split(L!("foobar"), ','), &["foobar"]);
|
||||||
|
assert_eq!(do_split(L!("1,2,3,4,5"), ','), &["1", "2", "3", "4", "5"]);
|
||||||
|
assert_eq!(
|
||||||
|
do_split(L!("Hello\nworld\nRust"), '\n'),
|
||||||
|
&["Hello", "world", "Rust"]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue