1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Unicode-intensive string manipulations.
13 //! This module provides functionality to `str` that requires the Unicode
14 //! methods provided by the unicode parts of the CharExt trait.
17 use core::iter::{Filter, FusedIterator};
20 /// An iterator over the non-whitespace substrings of a string,
21 /// separated by any amount of whitespace.
23 /// This struct is created by the [`split_whitespace`] method on [`str`].
24 /// See its documentation for more.
26 /// [`split_whitespace`]: ../../std/primitive.str.html#method.split_whitespace
27 /// [`str`]: ../../std/primitive.str.html
28 #[stable(feature = "split_whitespace", since = "1.1.0")]
29 #[derive(Clone, Debug)]
30 pub struct SplitWhitespace<'a> {
31 inner: Filter<Split<'a, IsWhitespace>, IsNotEmpty>,
34 /// Methods for Unicode string slices
35 #[allow(missing_docs)] // docs in liballoc
36 pub trait UnicodeStr {
37 fn split_whitespace<'a>(&'a self) -> SplitWhitespace<'a>;
38 fn is_whitespace(&self) -> bool;
39 fn is_alphanumeric(&self) -> bool;
40 fn trim(&self) -> &str;
41 fn trim_left(&self) -> &str;
42 fn trim_right(&self) -> &str;
45 impl UnicodeStr for str {
47 fn split_whitespace(&self) -> SplitWhitespace {
48 SplitWhitespace { inner: self.split(IsWhitespace).filter(IsNotEmpty) }
52 fn is_whitespace(&self) -> bool {
53 self.chars().all(|c| c.is_whitespace())
57 fn is_alphanumeric(&self) -> bool {
58 self.chars().all(|c| c.is_alphanumeric())
62 fn trim(&self) -> &str {
63 self.trim_matches(|c: char| c.is_whitespace())
67 fn trim_left(&self) -> &str {
68 self.trim_left_matches(|c: char| c.is_whitespace())
72 fn trim_right(&self) -> &str {
73 self.trim_right_matches(|c: char| c.is_whitespace())
77 /// Iterator adaptor for encoding `char`s to UTF-16.
79 #[allow(missing_debug_implementations)]
80 pub struct Utf16Encoder<I> {
85 impl<I> Utf16Encoder<I> {
86 /// Create a UTF-16 encoder from any `char` iterator.
87 pub fn new(chars: I) -> Utf16Encoder<I>
88 where I: Iterator<Item = char>
97 impl<I> Iterator for Utf16Encoder<I>
98 where I: Iterator<Item = char>
103 fn next(&mut self) -> Option<u16> {
105 let tmp = self.extra;
110 let mut buf = [0; 2];
111 self.chars.next().map(|ch| {
112 let n = CharExt::encode_utf16(ch, &mut buf).len();
121 fn size_hint(&self) -> (usize, Option<usize>) {
122 let (low, high) = self.chars.size_hint();
123 // every char gets either one u16 or two u16,
124 // so this iterator is between 1 or 2 times as
125 // long as the underlying iterator.
126 (low, high.and_then(|n| n.checked_mul(2)))
130 impl<I> FusedIterator for Utf16Encoder<I>
131 where I: FusedIterator<Item = char> {}
136 impl FnOnce<(char, )> for IsWhitespace {
140 extern "rust-call" fn call_once(mut self, arg: (char, )) -> bool {
145 impl FnMut<(char, )> for IsWhitespace {
147 extern "rust-call" fn call_mut(&mut self, arg: (char, )) -> bool {
148 arg.0.is_whitespace()
155 impl<'a, 'b> FnOnce<(&'a &'b str, )> for IsNotEmpty {
159 extern "rust-call" fn call_once(mut self, arg: (&&str, )) -> bool {
164 impl<'a, 'b> FnMut<(&'a &'b str, )> for IsNotEmpty {
166 extern "rust-call" fn call_mut(&mut self, arg: (&&str, )) -> bool {
172 #[stable(feature = "split_whitespace", since = "1.1.0")]
173 impl<'a> Iterator for SplitWhitespace<'a> {
176 fn next(&mut self) -> Option<&'a str> {
181 #[stable(feature = "split_whitespace", since = "1.1.0")]
182 impl<'a> DoubleEndedIterator for SplitWhitespace<'a> {
183 fn next_back(&mut self) -> Option<&'a str> {
184 self.inner.next_back()
188 #[stable(feature = "fused", since = "1.26.0")]
189 impl<'a> FusedIterator for SplitWhitespace<'a> {}