2014-04-30 23:06:36 -07:00
|
|
|
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
2014-07-14 20:46:04 -07:00
|
|
|
//
|
|
|
|
// ignore-lexer-test FIXME #15679
|
2014-04-30 23:06:36 -07:00
|
|
|
|
|
|
|
//! String manipulation
|
|
|
|
//!
|
|
|
|
//! For more details, see std::str
|
|
|
|
|
2014-05-28 19:53:37 -07:00
|
|
|
#![doc(primitive = "str")]
|
|
|
|
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
use self::Searcher::{Naive, TwoWay, TwoWayLong};
|
2014-11-06 00:05:53 -08:00
|
|
|
|
2015-01-23 10:54:32 -05:00
|
|
|
use clone::Clone;
|
2015-01-03 22:42:21 -05:00
|
|
|
use cmp::{self, Eq};
|
2014-04-30 23:06:36 -07:00
|
|
|
use default::Default;
|
2015-01-20 15:45:07 -08:00
|
|
|
use error::Error;
|
|
|
|
use fmt;
|
2015-01-03 00:28:23 -05:00
|
|
|
use iter::ExactSizeIterator;
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
use iter::{Map, Iterator, IteratorExt, DoubleEndedIterator};
|
2015-01-07 11:33:42 +13:00
|
|
|
use marker::Sized;
|
2014-11-20 10:11:15 -08:00
|
|
|
use mem;
|
2014-11-10 00:11:28 +11:00
|
|
|
use num::Int;
|
2015-01-07 11:58:31 -05:00
|
|
|
use ops::{Fn, FnMut};
|
2015-01-03 22:42:21 -05:00
|
|
|
use option::Option::{self, None, Some};
|
2014-12-19 08:57:12 -08:00
|
|
|
use ptr::PtrExt;
|
2014-11-20 10:11:15 -08:00
|
|
|
use raw::{Repr, Slice};
|
2015-01-03 22:42:21 -05:00
|
|
|
use result::Result::{self, Ok, Err};
|
|
|
|
use slice::{self, SliceExt};
|
2015-02-09 16:33:19 -08:00
|
|
|
use usize;
|
2014-04-30 23:06:36 -07:00
|
|
|
|
2014-12-30 21:54:17 +01:00
|
|
|
pub use self::pattern::{Pattern, Matcher, ReverseMatcher, DoubleEndedMatcher};
|
|
|
|
|
|
|
|
mod pattern;
|
|
|
|
|
2014-12-18 02:12:53 +01:00
|
|
|
macro_rules! delegate_iter {
|
2015-01-05 01:51:03 -05:00
|
|
|
(exact $te:ty : $ti:ty) => {
|
|
|
|
delegate_iter!{$te : $ti}
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a> ExactSizeIterator for $ti {
|
2014-12-18 02:12:53 +01:00
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn len(&self) -> uint {
|
2014-12-18 02:12:53 +01:00
|
|
|
self.0.len()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2015-01-05 01:51:03 -05:00
|
|
|
($te:ty : $ti:ty) => {
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a> Iterator for $ti {
|
|
|
|
type Item = $te;
|
|
|
|
|
2014-12-18 02:12:53 +01:00
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<$te> {
|
|
|
|
self.0.next()
|
|
|
|
}
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
2014-12-18 02:12:53 +01:00
|
|
|
self.0.size_hint()
|
|
|
|
}
|
|
|
|
}
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a> DoubleEndedIterator for $ti {
|
2014-12-18 02:12:53 +01:00
|
|
|
#[inline]
|
|
|
|
fn next_back(&mut self) -> Option<$te> {
|
|
|
|
self.0.next_back()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2015-01-05 01:51:03 -05:00
|
|
|
(pattern $te:ty : $ti:ty) => {
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, P: CharEq> Iterator for $ti {
|
|
|
|
type Item = $te;
|
|
|
|
|
2014-12-18 02:12:53 +01:00
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<$te> {
|
|
|
|
self.0.next()
|
|
|
|
}
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
2014-12-18 02:12:53 +01:00
|
|
|
self.0.size_hint()
|
|
|
|
}
|
|
|
|
}
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, P: CharEq> DoubleEndedIterator for $ti {
|
2014-12-18 02:12:53 +01:00
|
|
|
#[inline]
|
|
|
|
fn next_back(&mut self) -> Option<$te> {
|
|
|
|
self.0.next_back()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2015-01-05 01:51:03 -05:00
|
|
|
(pattern forward $te:ty : $ti:ty) => {
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, P: CharEq> Iterator for $ti {
|
|
|
|
type Item = $te;
|
|
|
|
|
2014-12-18 02:12:53 +01:00
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<$te> {
|
|
|
|
self.0.next()
|
|
|
|
}
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
2014-12-18 02:12:53 +01:00
|
|
|
self.0.size_hint()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-15 15:52:00 +11:00
|
|
|
/// A trait to abstract the idea of creating a new instance of a type from a
|
|
|
|
/// string.
|
2015-01-27 22:52:32 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-15 15:52:00 +11:00
|
|
|
pub trait FromStr {
|
2015-01-27 22:52:32 -08:00
|
|
|
/// The associated error which can be returned from parsing.
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
type Err;
|
|
|
|
|
2014-11-15 15:52:00 +11:00
|
|
|
/// Parses a string `s` to return an optional value of this type. If the
|
|
|
|
/// string is ill-formatted, the None is returned.
|
2015-01-27 22:52:32 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err>;
|
2014-11-15 15:52:00 +11:00
|
|
|
}
|
|
|
|
|
2015-01-27 22:52:32 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-15 15:52:00 +11:00
|
|
|
impl FromStr for bool {
|
2015-01-27 22:52:32 -08:00
|
|
|
type Err = ParseBoolError;
|
|
|
|
|
2014-11-15 15:52:00 +11:00
|
|
|
/// Parse a `bool` from a string.
|
|
|
|
///
|
2015-01-27 22:52:32 -08:00
|
|
|
/// Yields an `Option<bool>`, because `s` may or may not actually be
|
|
|
|
/// parseable.
|
2014-11-15 15:52:00 +11:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```rust
|
2015-01-27 22:52:32 -08:00
|
|
|
/// assert_eq!("true".parse(), Ok(true));
|
|
|
|
/// assert_eq!("false".parse(), Ok(false));
|
|
|
|
/// assert!("not even a boolean".parse::<bool>().is_err());
|
2014-11-15 15:52:00 +11:00
|
|
|
/// ```
|
|
|
|
#[inline]
|
2015-01-27 22:52:32 -08:00
|
|
|
fn from_str(s: &str) -> Result<bool, ParseBoolError> {
|
2014-11-15 15:52:00 +11:00
|
|
|
match s {
|
2015-01-27 22:52:32 -08:00
|
|
|
"true" => Ok(true),
|
|
|
|
"false" => Ok(false),
|
|
|
|
_ => Err(ParseBoolError { _priv: () }),
|
2014-11-15 15:52:00 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-27 22:52:32 -08:00
|
|
|
/// An error returned when parsing a `bool` from a string fails.
|
2015-01-30 12:26:44 -08:00
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
2014-12-30 21:54:17 +01:00
|
|
|
#[allow(missing_copy_implementations)]
|
2015-01-27 22:52:32 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
pub struct ParseBoolError { _priv: () }
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
impl fmt::Display for ParseBoolError {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
"provided string was not `true` or `false`".fmt(f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
impl Error for ParseBoolError {
|
|
|
|
fn description(&self) -> &str { "failed to parse bool" }
|
|
|
|
}
|
|
|
|
|
2014-04-30 23:06:36 -07:00
|
|
|
/*
|
|
|
|
Section: Creating a string
|
|
|
|
*/
|
|
|
|
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
/// Errors which can occur when attempting to interpret a byte slice as a `str`.
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Copy, Eq, PartialEq, Clone, Debug)]
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "error enumeration recently added and definitions may be refined")]
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
pub enum Utf8Error {
|
|
|
|
/// An invalid byte was detected at the byte offset given.
|
|
|
|
///
|
|
|
|
/// The offset is guaranteed to be in bounds of the slice in question, and
|
|
|
|
/// the byte at the specified offset was the first invalid byte in the
|
|
|
|
/// sequence detected.
|
2014-12-30 21:54:17 +01:00
|
|
|
InvalidByte(uint),
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
|
|
|
|
/// The byte slice was invalid because more bytes were needed but no more
|
|
|
|
/// bytes were available.
|
|
|
|
TooShort,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Converts a slice of bytes to a string slice without performing any
|
|
|
|
/// allocations.
|
2014-04-30 23:06:36 -07:00
|
|
|
///
|
|
|
|
/// Once the slice has been validated as utf-8, it is transmuted in-place and
|
|
|
|
/// returned as a '&str' instead of a '&[u8]'
|
|
|
|
///
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
/// # Failure
|
|
|
|
///
|
|
|
|
/// Returns `Err` if the slice is not utf-8 with a description as to why the
|
|
|
|
/// provided slice is not utf-8.
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
|
|
|
|
try!(run_utf8_validation_iterator(&mut v.iter()));
|
|
|
|
Ok(unsafe { from_utf8_unchecked(v) })
|
2014-11-20 10:11:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Converts a slice of bytes to a string slice without checking
|
|
|
|
/// that the string contains valid UTF-8.
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-20 10:11:15 -08:00
|
|
|
pub unsafe fn from_utf8_unchecked<'a>(v: &'a [u8]) -> &'a str {
|
|
|
|
mem::transmute(v)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Constructs a static string slice from a given raw pointer.
|
|
|
|
///
|
|
|
|
/// This function will read memory starting at `s` until it finds a 0, and then
|
|
|
|
/// transmute the memory up to that point as a string slice, returning the
|
|
|
|
/// corresponding `&'static str` value.
|
|
|
|
///
|
|
|
|
/// This function is unsafe because the caller must ensure the C string itself
|
|
|
|
/// has the static lifetime and that the memory `s` is valid up to and including
|
|
|
|
/// the first null byte.
|
|
|
|
///
|
|
|
|
/// # Panics
|
|
|
|
///
|
|
|
|
/// This function will panic if the string pointed to by `s` is not valid UTF-8.
|
2015-01-22 12:33:46 -08:00
|
|
|
#[unstable(feature = "core")]
|
|
|
|
#[deprecated(since = "1.0.0",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "use std::ffi::c_str_to_bytes + str::from_utf8")]
|
2014-11-20 10:11:15 -08:00
|
|
|
pub unsafe fn from_c_str(s: *const i8) -> &'static str {
|
|
|
|
let s = s as *const u8;
|
2015-01-22 14:08:56 +00:00
|
|
|
let mut len = 0;
|
2014-12-30 21:54:17 +01:00
|
|
|
while *s.offset(len as int) != 0 {
|
2015-01-22 14:08:56 +00:00
|
|
|
len += 1;
|
2014-11-20 10:11:15 -08:00
|
|
|
}
|
|
|
|
let v: &'static [u8] = ::mem::transmute(Slice { data: s, len: len });
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
from_utf8(v).ok().expect("from_c_str passed invalid utf-8 data")
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Something that can be used to compare against a character
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "definition may change as pattern-related methods are stabilized")]
|
2014-04-30 23:06:36 -07:00
|
|
|
pub trait CharEq {
|
|
|
|
/// Determine if the splitter should split at the given character
|
|
|
|
fn matches(&mut self, char) -> bool;
|
|
|
|
/// Indicate if this is only concerned about ASCII characters,
|
|
|
|
/// which can allow for a faster implementation.
|
|
|
|
fn only_ascii(&self) -> bool;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl CharEq for char {
|
|
|
|
#[inline]
|
|
|
|
fn matches(&mut self, c: char) -> bool { *self == c }
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn only_ascii(&self) -> bool { (*self as uint) < 128 }
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
2014-12-04 16:17:07 -05:00
|
|
|
impl<F> CharEq for F where F: FnMut(char) -> bool {
|
2014-04-30 23:06:36 -07:00
|
|
|
#[inline]
|
|
|
|
fn matches(&mut self, c: char) -> bool { (*self)(c) }
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn only_ascii(&self) -> bool { false }
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> CharEq for &'a [char] {
|
|
|
|
#[inline]
|
|
|
|
fn matches(&mut self, c: char) -> bool {
|
2014-12-05 15:56:25 -08:00
|
|
|
self.iter().any(|&m| { let mut m = m; m.matches(c) })
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn only_ascii(&self) -> bool {
|
|
|
|
self.iter().all(|m| m.only_ascii())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-24 09:15:42 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-01-20 15:45:07 -08:00
|
|
|
impl Error for Utf8Error {
|
|
|
|
fn description(&self) -> &str {
|
|
|
|
match *self {
|
|
|
|
Utf8Error::TooShort => "invalid utf-8: not enough bytes",
|
|
|
|
Utf8Error::InvalidByte(..) => "invalid utf-8: corrupt contents",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-24 09:15:42 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-01-20 15:45:07 -08:00
|
|
|
impl fmt::Display for Utf8Error {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
match *self {
|
|
|
|
Utf8Error::InvalidByte(n) => {
|
|
|
|
write!(f, "invalid utf-8: invalid byte at index {}", n)
|
|
|
|
}
|
|
|
|
Utf8Error::TooShort => {
|
|
|
|
write!(f, "invalid utf-8: byte slice too short")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-30 23:06:36 -07:00
|
|
|
/*
|
|
|
|
Section: Iterators
|
|
|
|
*/
|
|
|
|
|
2014-07-17 19:34:07 +02:00
|
|
|
/// Iterator for the char (representing *Unicode Scalar Values*) of a string
|
|
|
|
///
|
|
|
|
/// Created with the method `.chars()`.
|
2015-01-23 10:54:32 -05:00
|
|
|
#[derive(Clone)]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-04-30 23:06:36 -07:00
|
|
|
pub struct Chars<'a> {
|
2014-12-19 21:52:10 +01:00
|
|
|
iter: slice::Iter<'a, u8>
|
2014-07-17 19:34:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Return the initial codepoint accumulator for the first byte.
|
|
|
|
// The first byte is special, only want bottom 5 bits for width 2, 4 bits
|
|
|
|
// for width 3, and 3 bits for width 4
|
2014-11-14 09:18:10 -08:00
|
|
|
macro_rules! utf8_first_byte {
|
2014-07-17 19:34:07 +02:00
|
|
|
($byte:expr, $width:expr) => (($byte & (0x7F >> $width)) as u32)
|
2014-11-14 09:18:10 -08:00
|
|
|
}
|
2014-07-17 19:34:07 +02:00
|
|
|
|
|
|
|
// return the value of $ch updated with continuation byte $byte
|
2014-11-14 09:18:10 -08:00
|
|
|
macro_rules! utf8_acc_cont_byte {
|
2014-07-18 00:59:49 +02:00
|
|
|
($ch:expr, $byte:expr) => (($ch << 6) | ($byte & CONT_MASK) as u32)
|
2014-11-14 09:18:10 -08:00
|
|
|
}
|
2014-07-17 19:34:07 +02:00
|
|
|
|
2014-11-14 09:18:10 -08:00
|
|
|
macro_rules! utf8_is_cont_byte {
|
2014-07-18 00:59:49 +02:00
|
|
|
($byte:expr) => (($byte & !CONT_MASK) == TAG_CONT_U8)
|
2014-11-14 09:18:10 -08:00
|
|
|
}
|
2014-07-17 19:34:07 +02:00
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn unwrap_or_0(opt: Option<&u8>) -> u8 {
|
|
|
|
match opt {
|
|
|
|
Some(&byte) => byte,
|
|
|
|
None => 0,
|
|
|
|
}
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
2015-01-21 15:55:31 -08:00
|
|
|
/// Reads the next code point out of a byte iterator (assuming a
|
|
|
|
/// UTF-8-like encoding).
|
2015-01-25 19:03:10 -08:00
|
|
|
#[unstable(feature = "core")]
|
2015-01-21 15:55:31 -08:00
|
|
|
pub fn next_code_point(bytes: &mut slice::Iter<u8>) -> Option<u32> {
|
|
|
|
// Decode UTF-8
|
|
|
|
let x = match bytes.next() {
|
|
|
|
None => return None,
|
|
|
|
Some(&next_byte) if next_byte < 128 => return Some(next_byte as u32),
|
|
|
|
Some(&next_byte) => next_byte,
|
|
|
|
};
|
|
|
|
|
|
|
|
// Multibyte case follows
|
|
|
|
// Decode from a byte combination out of: [[[x y] z] w]
|
|
|
|
// NOTE: Performance is sensitive to the exact formulation here
|
|
|
|
let init = utf8_first_byte!(x, 2);
|
|
|
|
let y = unwrap_or_0(bytes.next());
|
|
|
|
let mut ch = utf8_acc_cont_byte!(init, y);
|
|
|
|
if x >= 0xE0 {
|
|
|
|
// [[x y z] w] case
|
|
|
|
// 5th bit in 0xE0 .. 0xEF is always clear, so `init` is still valid
|
|
|
|
let z = unwrap_or_0(bytes.next());
|
|
|
|
let y_z = utf8_acc_cont_byte!((y & CONT_MASK) as u32, z);
|
|
|
|
ch = init << 12 | y_z;
|
|
|
|
if x >= 0xF0 {
|
|
|
|
// [x y z w] case
|
|
|
|
// use only the lower 3 bits of `init`
|
|
|
|
let w = unwrap_or_0(bytes.next());
|
|
|
|
ch = (init & 7) << 18 | utf8_acc_cont_byte!(y_z, w);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Some(ch)
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a> Iterator for Chars<'a> {
|
|
|
|
type Item = char;
|
|
|
|
|
2014-04-30 23:06:36 -07:00
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<char> {
|
2015-01-21 15:55:31 -08:00
|
|
|
next_code_point(&mut self.iter).map(|ch| {
|
|
|
|
// str invariant says `ch` is a valid Unicode Scalar Value
|
|
|
|
unsafe {
|
|
|
|
mem::transmute(ch)
|
2014-07-17 19:34:07 +02:00
|
|
|
}
|
2015-01-21 15:55:31 -08:00
|
|
|
})
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
2014-07-17 19:34:07 +02:00
|
|
|
let (len, _) = self.iter.size_hint();
|
|
|
|
(len.saturating_add(3) / 4, Some(len))
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a> DoubleEndedIterator for Chars<'a> {
|
2014-04-30 23:06:36 -07:00
|
|
|
#[inline]
|
|
|
|
fn next_back(&mut self) -> Option<char> {
|
2014-07-19 00:02:30 +02:00
|
|
|
let w = match self.iter.next_back() {
|
|
|
|
None => return None,
|
|
|
|
Some(&back_byte) if back_byte < 128 => return Some(back_byte as char),
|
|
|
|
Some(&back_byte) => back_byte,
|
|
|
|
};
|
|
|
|
|
|
|
|
// Multibyte case follows
|
|
|
|
// Decode from a byte combination out of: [x [y [z w]]]
|
|
|
|
let mut ch;
|
|
|
|
let z = unwrap_or_0(self.iter.next_back());
|
|
|
|
ch = utf8_first_byte!(z, 2);
|
|
|
|
if utf8_is_cont_byte!(z) {
|
|
|
|
let y = unwrap_or_0(self.iter.next_back());
|
|
|
|
ch = utf8_first_byte!(y, 3);
|
|
|
|
if utf8_is_cont_byte!(y) {
|
|
|
|
let x = unwrap_or_0(self.iter.next_back());
|
|
|
|
ch = utf8_first_byte!(x, 4);
|
|
|
|
ch = utf8_acc_cont_byte!(ch, y);
|
2014-07-17 19:34:07 +02:00
|
|
|
}
|
2014-07-19 00:02:30 +02:00
|
|
|
ch = utf8_acc_cont_byte!(ch, z);
|
2014-07-17 19:34:07 +02:00
|
|
|
}
|
2014-07-19 00:02:30 +02:00
|
|
|
ch = utf8_acc_cont_byte!(ch, w);
|
2014-07-17 19:34:07 +02:00
|
|
|
|
2014-07-19 00:02:30 +02:00
|
|
|
// str invariant says `ch` is a valid Unicode Scalar Value
|
|
|
|
unsafe {
|
|
|
|
Some(mem::transmute(ch))
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// External iterator for a string's characters and their byte offsets.
|
|
|
|
/// Use with the `std::iter` module.
|
2015-01-03 22:54:18 -05:00
|
|
|
#[derive(Clone)]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
pub struct CharIndices<'a> {
|
2014-12-30 21:54:17 +01:00
|
|
|
front_offset: uint,
|
2014-04-30 23:06:36 -07:00
|
|
|
iter: Chars<'a>,
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a> Iterator for CharIndices<'a> {
|
2014-12-30 21:54:17 +01:00
|
|
|
type Item = (uint, char);
|
2014-12-29 16:18:41 -05:00
|
|
|
|
2014-04-30 23:06:36 -07:00
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn next(&mut self) -> Option<(uint, char)> {
|
2014-07-19 15:39:02 +02:00
|
|
|
let (pre_len, _) = self.iter.iter.size_hint();
|
2014-07-17 19:34:07 +02:00
|
|
|
match self.iter.next() {
|
|
|
|
None => None,
|
|
|
|
Some(ch) => {
|
2014-07-19 15:39:02 +02:00
|
|
|
let index = self.front_offset;
|
2014-07-17 19:34:07 +02:00
|
|
|
let (len, _) = self.iter.iter.size_hint();
|
2014-07-19 15:39:02 +02:00
|
|
|
self.front_offset += pre_len - len;
|
2014-07-17 19:34:07 +02:00
|
|
|
Some((index, ch))
|
|
|
|
}
|
|
|
|
}
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
2014-04-30 23:06:36 -07:00
|
|
|
self.iter.size_hint()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a> DoubleEndedIterator for CharIndices<'a> {
|
2014-04-30 23:06:36 -07:00
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn next_back(&mut self) -> Option<(uint, char)> {
|
2014-07-17 19:34:07 +02:00
|
|
|
match self.iter.next_back() {
|
|
|
|
None => None,
|
|
|
|
Some(ch) => {
|
|
|
|
let (len, _) = self.iter.iter.size_hint();
|
2014-07-19 15:39:02 +02:00
|
|
|
let index = self.front_offset + len;
|
|
|
|
Some((index, ch))
|
2014-07-17 19:34:07 +02:00
|
|
|
}
|
|
|
|
}
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// External iterator for a string's bytes.
|
|
|
|
/// Use with the `std::iter` module.
|
2014-12-18 02:12:53 +01:00
|
|
|
///
|
|
|
|
/// Created with `StrExt::bytes`
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-01-03 22:54:18 -05:00
|
|
|
#[derive(Clone)]
|
2015-02-01 12:15:36 -08:00
|
|
|
pub struct Bytes<'a>(Map<slice::Iter<'a, u8>, BytesDeref>);
|
2015-01-05 01:51:03 -05:00
|
|
|
delegate_iter!{exact u8 : Bytes<'a>}
|
2014-12-18 22:16:48 -05:00
|
|
|
|
2014-12-18 02:12:53 +01:00
|
|
|
/// A temporary fn new type that ensures that the `Bytes` iterator
|
2014-12-18 22:16:48 -05:00
|
|
|
/// is cloneable.
|
2015-01-03 22:54:18 -05:00
|
|
|
#[derive(Copy, Clone)]
|
2014-12-18 02:12:53 +01:00
|
|
|
struct BytesDeref;
|
2014-12-18 22:16:48 -05:00
|
|
|
|
2015-01-10 11:54:15 -05:00
|
|
|
impl<'a> Fn<(&'a u8,)> for BytesDeref {
|
|
|
|
type Output = u8;
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
extern "rust-call" fn call(&self, (ptr,): (&'a u8,)) -> u8 {
|
|
|
|
*ptr
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-30 23:06:36 -07:00
|
|
|
/// An iterator over the substrings of a string, separated by `sep`.
|
2015-01-03 22:54:18 -05:00
|
|
|
#[derive(Clone)]
|
2015-01-01 23:53:35 -08:00
|
|
|
struct CharSplits<'a, Sep> {
|
2014-04-30 23:06:36 -07:00
|
|
|
/// The slice remaining to be iterated
|
|
|
|
string: &'a str,
|
|
|
|
sep: Sep,
|
|
|
|
/// Whether an empty string at the end is allowed
|
|
|
|
allow_trailing_empty: bool,
|
|
|
|
only_ascii: bool,
|
|
|
|
finished: bool,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// An iterator over the substrings of a string, separated by `sep`,
|
|
|
|
/// splitting at most `count` times.
|
2015-01-03 22:54:18 -05:00
|
|
|
#[derive(Clone)]
|
2015-01-01 23:53:35 -08:00
|
|
|
struct CharSplitsN<'a, Sep> {
|
2014-04-30 23:06:36 -07:00
|
|
|
iter: CharSplits<'a, Sep>,
|
|
|
|
/// The number of splits remaining
|
2014-12-30 21:54:17 +01:00
|
|
|
count: uint,
|
2014-04-30 23:06:36 -07:00
|
|
|
invert: bool,
|
|
|
|
}
|
|
|
|
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
/// An iterator over the lines of a string, separated by `\n`.
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
pub struct Lines<'a> {
|
|
|
|
inner: CharSplits<'a, char>,
|
|
|
|
}
|
|
|
|
|
2014-04-30 23:06:36 -07:00
|
|
|
/// An iterator over the lines of a string, separated by either `\n` or (`\r\n`).
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
pub struct LinesAny<'a> {
|
2015-02-01 12:15:36 -08:00
|
|
|
inner: Map<Lines<'a>, fn(&str) -> &str>,
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
}
|
2014-04-30 23:06:36 -07:00
|
|
|
|
|
|
|
impl<'a, Sep> CharSplits<'a, Sep> {
|
|
|
|
#[inline]
|
|
|
|
fn get_end(&mut self) -> Option<&'a str> {
|
|
|
|
if !self.finished && (self.allow_trailing_empty || self.string.len() > 0) {
|
|
|
|
self.finished = true;
|
|
|
|
Some(self.string)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, Sep: CharEq> Iterator for CharSplits<'a, Sep> {
|
|
|
|
type Item = &'a str;
|
|
|
|
|
2014-04-30 23:06:36 -07:00
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<&'a str> {
|
|
|
|
if self.finished { return None }
|
|
|
|
|
|
|
|
let mut next_split = None;
|
|
|
|
if self.only_ascii {
|
|
|
|
for (idx, byte) in self.string.bytes().enumerate() {
|
|
|
|
if self.sep.matches(byte as char) && byte < 128u8 {
|
|
|
|
next_split = Some((idx, idx + 1));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (idx, ch) in self.string.char_indices() {
|
|
|
|
if self.sep.matches(ch) {
|
|
|
|
next_split = Some((idx, self.string.char_range_at(idx).next));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
match next_split {
|
|
|
|
Some((a, b)) => unsafe {
|
2014-11-20 10:11:15 -08:00
|
|
|
let elt = self.string.slice_unchecked(0, a);
|
|
|
|
self.string = self.string.slice_unchecked(b, self.string.len());
|
2014-04-30 23:06:36 -07:00
|
|
|
Some(elt)
|
|
|
|
},
|
|
|
|
None => self.get_end(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, Sep: CharEq> DoubleEndedIterator for CharSplits<'a, Sep> {
|
2014-04-30 23:06:36 -07:00
|
|
|
#[inline]
|
|
|
|
fn next_back(&mut self) -> Option<&'a str> {
|
|
|
|
if self.finished { return None }
|
|
|
|
|
|
|
|
if !self.allow_trailing_empty {
|
|
|
|
self.allow_trailing_empty = true;
|
|
|
|
match self.next_back() {
|
|
|
|
Some(elt) if !elt.is_empty() => return Some(elt),
|
|
|
|
_ => if self.finished { return None }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let len = self.string.len();
|
|
|
|
let mut next_split = None;
|
|
|
|
|
|
|
|
if self.only_ascii {
|
|
|
|
for (idx, byte) in self.string.bytes().enumerate().rev() {
|
|
|
|
if self.sep.matches(byte as char) && byte < 128u8 {
|
|
|
|
next_split = Some((idx, idx + 1));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (idx, ch) in self.string.char_indices().rev() {
|
|
|
|
if self.sep.matches(ch) {
|
|
|
|
next_split = Some((idx, self.string.char_range_at(idx).next));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
match next_split {
|
|
|
|
Some((a, b)) => unsafe {
|
2014-11-20 10:11:15 -08:00
|
|
|
let elt = self.string.slice_unchecked(b, len);
|
|
|
|
self.string = self.string.slice_unchecked(0, a);
|
2014-04-30 23:06:36 -07:00
|
|
|
Some(elt)
|
|
|
|
},
|
|
|
|
None => { self.finished = true; Some(self.string) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a, Sep: CharEq> Iterator for CharSplitsN<'a, Sep> {
|
|
|
|
type Item = &'a str;
|
|
|
|
|
2014-04-30 23:06:36 -07:00
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<&'a str> {
|
|
|
|
if self.count != 0 {
|
|
|
|
self.count -= 1;
|
|
|
|
if self.invert { self.iter.next_back() } else { self.iter.next() }
|
|
|
|
} else {
|
|
|
|
self.iter.get_end()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-11 19:34:33 -05:00
|
|
|
/// The internal state of an iterator that searches for matches of a substring
|
|
|
|
/// within a larger string using naive search
|
2015-01-03 22:54:18 -05:00
|
|
|
#[derive(Clone)]
|
2014-05-11 19:34:33 -05:00
|
|
|
struct NaiveSearcher {
|
2014-12-30 21:54:17 +01:00
|
|
|
position: uint
|
2014-05-11 19:34:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl NaiveSearcher {
|
|
|
|
fn new() -> NaiveSearcher {
|
|
|
|
NaiveSearcher { position: 0 }
|
|
|
|
}
|
|
|
|
|
2014-12-30 21:54:17 +01:00
|
|
|
fn next(&mut self, haystack: &[u8], needle: &[u8]) -> Option<(uint, uint)> {
|
2014-05-11 19:34:33 -05:00
|
|
|
while self.position + needle.len() <= haystack.len() {
|
2015-01-07 11:58:31 -05:00
|
|
|
if &haystack[self.position .. self.position + needle.len()] == needle {
|
2014-07-19 00:45:17 +12:00
|
|
|
let match_pos = self.position;
|
2014-05-11 19:34:33 -05:00
|
|
|
self.position += needle.len(); // add 1 for all matches
|
2014-07-19 00:45:17 +12:00
|
|
|
return Some((match_pos, match_pos + needle.len()));
|
2014-05-11 19:34:33 -05:00
|
|
|
} else {
|
|
|
|
self.position += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The internal state of an iterator that searches for matches of a substring
|
|
|
|
/// within a larger string using two-way search
|
2015-01-03 22:54:18 -05:00
|
|
|
#[derive(Clone)]
|
2014-05-11 19:34:33 -05:00
|
|
|
struct TwoWaySearcher {
|
|
|
|
// constants
|
2014-12-30 21:54:17 +01:00
|
|
|
crit_pos: uint,
|
|
|
|
period: uint,
|
2014-05-11 19:34:33 -05:00
|
|
|
byteset: u64,
|
|
|
|
|
|
|
|
// variables
|
2014-12-30 21:54:17 +01:00
|
|
|
position: uint,
|
|
|
|
memory: uint
|
2014-05-11 19:34:33 -05:00
|
|
|
}
|
|
|
|
|
2014-09-02 01:57:23 -04:00
|
|
|
/*
|
|
|
|
This is the Two-Way search algorithm, which was introduced in the paper:
|
|
|
|
Crochemore, M., Perrin, D., 1991, Two-way string-matching, Journal of the ACM 38(3):651-675.
|
|
|
|
|
|
|
|
Here's some background information.
|
|
|
|
|
|
|
|
A *word* is a string of symbols. The *length* of a word should be a familiar
|
|
|
|
notion, and here we denote it for any word x by |x|.
|
|
|
|
(We also allow for the possibility of the *empty word*, a word of length zero).
|
|
|
|
|
|
|
|
If x is any non-empty word, then an integer p with 0 < p <= |x| is said to be a
|
|
|
|
*period* for x iff for all i with 0 <= i <= |x| - p - 1, we have x[i] == x[i+p].
|
|
|
|
For example, both 1 and 2 are periods for the string "aa". As another example,
|
|
|
|
the only period of the string "abcd" is 4.
|
|
|
|
|
|
|
|
We denote by period(x) the *smallest* period of x (provided that x is non-empty).
|
|
|
|
This is always well-defined since every non-empty word x has at least one period,
|
|
|
|
|x|. We sometimes call this *the period* of x.
|
|
|
|
|
|
|
|
If u, v and x are words such that x = uv, where uv is the concatenation of u and
|
|
|
|
v, then we say that (u, v) is a *factorization* of x.
|
|
|
|
|
|
|
|
Let (u, v) be a factorization for a word x. Then if w is a non-empty word such
|
|
|
|
that both of the following hold
|
|
|
|
|
|
|
|
- either w is a suffix of u or u is a suffix of w
|
|
|
|
- either w is a prefix of v or v is a prefix of w
|
|
|
|
|
|
|
|
then w is said to be a *repetition* for the factorization (u, v).
|
|
|
|
|
|
|
|
Just to unpack this, there are four possibilities here. Let w = "abc". Then we
|
|
|
|
might have:
|
|
|
|
|
|
|
|
- w is a suffix of u and w is a prefix of v. ex: ("lolabc", "abcde")
|
|
|
|
- w is a suffix of u and v is a prefix of w. ex: ("lolabc", "ab")
|
|
|
|
- u is a suffix of w and w is a prefix of v. ex: ("bc", "abchi")
|
|
|
|
- u is a suffix of w and v is a prefix of w. ex: ("bc", "a")
|
|
|
|
|
|
|
|
Note that the word vu is a repetition for any factorization (u,v) of x = uv,
|
|
|
|
so every factorization has at least one repetition.
|
|
|
|
|
|
|
|
If x is a string and (u, v) is a factorization for x, then a *local period* for
|
|
|
|
(u, v) is an integer r such that there is some word w such that |w| = r and w is
|
|
|
|
a repetition for (u, v).
|
|
|
|
|
|
|
|
We denote by local_period(u, v) the smallest local period of (u, v). We sometimes
|
|
|
|
call this *the local period* of (u, v). Provided that x = uv is non-empty, this
|
|
|
|
is well-defined (because each non-empty word has at least one factorization, as
|
|
|
|
noted above).
|
|
|
|
|
|
|
|
It can be proven that the following is an equivalent definition of a local period
|
|
|
|
for a factorization (u, v): any positive integer r such that x[i] == x[i+r] for
|
|
|
|
all i such that |u| - r <= i <= |u| - 1 and such that both x[i] and x[i+r] are
|
|
|
|
defined. (i.e. i > 0 and i + r < |x|).
|
|
|
|
|
|
|
|
Using the above reformulation, it is easy to prove that
|
|
|
|
|
|
|
|
1 <= local_period(u, v) <= period(uv)
|
|
|
|
|
|
|
|
A factorization (u, v) of x such that local_period(u,v) = period(x) is called a
|
|
|
|
*critical factorization*.
|
|
|
|
|
|
|
|
The algorithm hinges on the following theorem, which is stated without proof:
|
|
|
|
|
|
|
|
**Critical Factorization Theorem** Any word x has at least one critical
|
|
|
|
factorization (u, v) such that |u| < period(x).
|
|
|
|
|
|
|
|
The purpose of maximal_suffix is to find such a critical factorization.
|
|
|
|
|
|
|
|
*/
|
2014-05-11 19:34:33 -05:00
|
|
|
impl TwoWaySearcher {
|
|
|
|
fn new(needle: &[u8]) -> TwoWaySearcher {
|
2015-01-13 17:45:04 +01:00
|
|
|
let (crit_pos_false, period_false) = TwoWaySearcher::maximal_suffix(needle, false);
|
|
|
|
let (crit_pos_true, period_true) = TwoWaySearcher::maximal_suffix(needle, true);
|
|
|
|
|
|
|
|
let (crit_pos, period) =
|
|
|
|
if crit_pos_false > crit_pos_true {
|
|
|
|
(crit_pos_false, period_false)
|
|
|
|
} else {
|
|
|
|
(crit_pos_true, period_true)
|
|
|
|
};
|
2014-05-11 19:34:33 -05:00
|
|
|
|
2014-09-02 01:57:23 -04:00
|
|
|
// This isn't in the original algorithm, as far as I'm aware.
|
2014-04-21 17:58:52 -04:00
|
|
|
let byteset = needle.iter()
|
2014-12-30 21:54:17 +01:00
|
|
|
.fold(0, |a, &b| (1 << ((b & 0x3f) as uint)) | a);
|
2014-05-11 19:34:33 -05:00
|
|
|
|
2014-09-02 01:57:23 -04:00
|
|
|
// A particularly readable explanation of what's going on here can be found
|
|
|
|
// in Crochemore and Rytter's book "Text Algorithms", ch 13. Specifically
|
|
|
|
// see the code for "Algorithm CP" on p. 323.
|
2014-08-20 13:57:54 -04:00
|
|
|
//
|
2014-09-02 01:57:23 -04:00
|
|
|
// What's going on is we have some critical factorization (u, v) of the
|
|
|
|
// needle, and we want to determine whether u is a suffix of
|
2015-01-12 16:59:18 -05:00
|
|
|
// &v[..period]. If it is, we use "Algorithm CP1". Otherwise we use
|
2014-09-02 01:57:23 -04:00
|
|
|
// "Algorithm CP2", which is optimized for when the period of the needle
|
|
|
|
// is large.
|
2015-01-12 16:59:18 -05:00
|
|
|
if &needle[..crit_pos] == &needle[period.. period + crit_pos] {
|
2014-05-11 19:34:33 -05:00
|
|
|
TwoWaySearcher {
|
2014-07-19 00:45:17 +12:00
|
|
|
crit_pos: crit_pos,
|
2014-05-11 19:34:33 -05:00
|
|
|
period: period,
|
|
|
|
byteset: byteset,
|
|
|
|
|
|
|
|
position: 0,
|
|
|
|
memory: 0
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
TwoWaySearcher {
|
2014-07-19 00:45:17 +12:00
|
|
|
crit_pos: crit_pos,
|
|
|
|
period: cmp::max(crit_pos, needle.len() - crit_pos) + 1,
|
2014-05-11 19:34:33 -05:00
|
|
|
byteset: byteset,
|
|
|
|
|
|
|
|
position: 0,
|
2015-02-09 16:33:19 -08:00
|
|
|
memory: usize::MAX // Dummy value to signify that the period is long
|
2014-05-11 19:34:33 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-02 01:57:23 -04:00
|
|
|
// One of the main ideas of Two-Way is that we factorize the needle into
|
|
|
|
// two halves, (u, v), and begin trying to find v in the haystack by scanning
|
|
|
|
// left to right. If v matches, we try to match u by scanning right to left.
|
|
|
|
// How far we can jump when we encounter a mismatch is all based on the fact
|
|
|
|
// that (u, v) is a critical factorization for the needle.
|
2014-05-11 19:34:33 -05:00
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn next(&mut self, haystack: &[u8], needle: &[u8], long_period: bool) -> Option<(uint, uint)> {
|
2014-05-11 19:34:33 -05:00
|
|
|
'search: loop {
|
|
|
|
// Check that we have room to search in
|
|
|
|
if self.position + needle.len() > haystack.len() {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Quickly skip by large portions unrelated to our substring
|
2014-04-21 17:58:52 -04:00
|
|
|
if (self.byteset >>
|
|
|
|
((haystack[self.position + needle.len() - 1] & 0x3f)
|
2014-12-30 21:54:17 +01:00
|
|
|
as uint)) & 1 == 0 {
|
2014-05-11 19:34:33 -05:00
|
|
|
self.position += needle.len();
|
2014-09-02 01:53:12 -04:00
|
|
|
if !long_period {
|
|
|
|
self.memory = 0;
|
|
|
|
}
|
2014-05-11 19:34:33 -05:00
|
|
|
continue 'search;
|
|
|
|
}
|
|
|
|
|
|
|
|
// See if the right part of the needle matches
|
2014-07-19 00:45:17 +12:00
|
|
|
let start = if long_period { self.crit_pos }
|
|
|
|
else { cmp::max(self.crit_pos, self.memory) };
|
2015-01-26 16:05:07 -05:00
|
|
|
for i in start..needle.len() {
|
2014-05-11 19:34:33 -05:00
|
|
|
if needle[i] != haystack[self.position + i] {
|
2014-07-19 00:45:17 +12:00
|
|
|
self.position += i - self.crit_pos + 1;
|
|
|
|
if !long_period {
|
2014-05-11 19:34:33 -05:00
|
|
|
self.memory = 0;
|
|
|
|
}
|
|
|
|
continue 'search;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// See if the left part of the needle matches
|
2014-07-19 00:45:17 +12:00
|
|
|
let start = if long_period { 0 } else { self.memory };
|
2015-01-26 15:44:22 -05:00
|
|
|
for i in (start..self.crit_pos).rev() {
|
2014-05-11 19:34:33 -05:00
|
|
|
if needle[i] != haystack[self.position + i] {
|
|
|
|
self.position += self.period;
|
2014-07-19 00:45:17 +12:00
|
|
|
if !long_period {
|
2014-05-11 19:34:33 -05:00
|
|
|
self.memory = needle.len() - self.period;
|
|
|
|
}
|
|
|
|
continue 'search;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// We have found a match!
|
2014-07-19 00:45:17 +12:00
|
|
|
let match_pos = self.position;
|
2014-05-11 19:34:33 -05:00
|
|
|
self.position += needle.len(); // add self.period for all matches
|
2014-07-19 00:45:17 +12:00
|
|
|
if !long_period {
|
2014-05-11 19:34:33 -05:00
|
|
|
self.memory = 0; // set to needle.len() - self.period for all matches
|
|
|
|
}
|
2014-07-19 00:45:17 +12:00
|
|
|
return Some((match_pos, match_pos + needle.len()));
|
2014-05-11 19:34:33 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-02 01:57:23 -04:00
|
|
|
// Computes a critical factorization (u, v) of `arr`.
|
|
|
|
// Specifically, returns (i, p), where i is the starting index of v in some
|
|
|
|
// critical factorization (u, v) and p = period(v)
|
2014-05-11 19:34:33 -05:00
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn maximal_suffix(arr: &[u8], reversed: bool) -> (uint, uint) {
|
2014-05-11 19:34:33 -05:00
|
|
|
let mut left = -1; // Corresponds to i in the paper
|
|
|
|
let mut right = 0; // Corresponds to j in the paper
|
|
|
|
let mut offset = 1; // Corresponds to k in the paper
|
|
|
|
let mut period = 1; // Corresponds to p in the paper
|
|
|
|
|
|
|
|
while right + offset < arr.len() {
|
|
|
|
let a;
|
|
|
|
let b;
|
|
|
|
if reversed {
|
|
|
|
a = arr[left + offset];
|
|
|
|
b = arr[right + offset];
|
|
|
|
} else {
|
|
|
|
a = arr[right + offset];
|
|
|
|
b = arr[left + offset];
|
|
|
|
}
|
|
|
|
if a < b {
|
|
|
|
// Suffix is smaller, period is entire prefix so far.
|
|
|
|
right += offset;
|
|
|
|
offset = 1;
|
|
|
|
period = right - left;
|
|
|
|
} else if a == b {
|
|
|
|
// Advance through repetition of the current period.
|
|
|
|
if offset == period {
|
|
|
|
right += offset;
|
|
|
|
offset = 1;
|
|
|
|
} else {
|
|
|
|
offset += 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Suffix is larger, start over from current location.
|
|
|
|
left = right;
|
|
|
|
right += 1;
|
|
|
|
offset = 1;
|
|
|
|
period = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
(left + 1, period)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// The internal state of an iterator that searches for matches of a substring
|
2014-06-08 13:22:49 -04:00
|
|
|
/// within a larger string using a dynamically chosen search algorithm
|
2015-01-03 22:54:18 -05:00
|
|
|
#[derive(Clone)]
|
2014-05-11 19:34:33 -05:00
|
|
|
enum Searcher {
|
2014-12-30 21:54:17 +01:00
|
|
|
EmptyNeedle { pos: usize, done: bool },
|
2014-05-11 19:34:33 -05:00
|
|
|
Naive(NaiveSearcher),
|
|
|
|
TwoWay(TwoWaySearcher),
|
|
|
|
TwoWayLong(TwoWaySearcher)
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Searcher {
|
|
|
|
fn new(haystack: &[u8], needle: &[u8]) -> Searcher {
|
2014-12-30 21:54:17 +01:00
|
|
|
if needle.len() == 0 {
|
|
|
|
Searcher::EmptyNeedle {
|
|
|
|
pos: 0,
|
|
|
|
done: false
|
|
|
|
}
|
2014-05-11 19:34:33 -05:00
|
|
|
// FIXME: Tune this.
|
2014-09-12 15:03:50 +02:00
|
|
|
// FIXME(#16715): This unsigned integer addition will probably not
|
|
|
|
// overflow because that would mean that the memory almost solely
|
|
|
|
// consists of the needle. Needs #16715 to be formally fixed.
|
2014-12-30 21:54:17 +01:00
|
|
|
} else if needle.len() + 20 > haystack.len() {
|
2014-05-11 19:34:33 -05:00
|
|
|
Naive(NaiveSearcher::new())
|
|
|
|
} else {
|
|
|
|
let searcher = TwoWaySearcher::new(needle);
|
2015-02-09 16:33:19 -08:00
|
|
|
if searcher.memory == usize::MAX { // If the period is long
|
2014-05-11 19:34:33 -05:00
|
|
|
TwoWayLong(searcher)
|
|
|
|
} else {
|
|
|
|
TwoWay(searcher)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-30 23:06:36 -07:00
|
|
|
/// An iterator over the start and end indices of the matches of a
|
|
|
|
/// substring within a larger string
|
2015-01-03 22:54:18 -05:00
|
|
|
#[derive(Clone)]
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "type may be removed")]
|
2014-04-30 23:06:36 -07:00
|
|
|
pub struct MatchIndices<'a> {
|
2014-05-11 19:34:33 -05:00
|
|
|
// constants
|
2014-04-30 23:06:36 -07:00
|
|
|
haystack: &'a str,
|
|
|
|
needle: &'a str,
|
2014-05-11 19:34:33 -05:00
|
|
|
searcher: Searcher
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// An iterator over the substrings of a string separated by a given
|
|
|
|
/// search string
|
2015-01-03 22:54:18 -05:00
|
|
|
#[derive(Clone)]
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core", reason = "type may be removed")]
|
2014-12-18 02:12:53 +01:00
|
|
|
pub struct SplitStr<'a> {
|
2014-04-30 23:06:36 -07:00
|
|
|
it: MatchIndices<'a>,
|
2014-12-30 21:54:17 +01:00
|
|
|
last_end: uint,
|
2014-04-30 23:06:36 -07:00
|
|
|
finished: bool
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a> Iterator for MatchIndices<'a> {
|
2014-12-30 21:54:17 +01:00
|
|
|
type Item = (uint, uint);
|
2014-12-29 16:18:41 -05:00
|
|
|
|
2014-04-30 23:06:36 -07:00
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn next(&mut self) -> Option<(uint, uint)> {
|
2014-05-11 19:34:33 -05:00
|
|
|
match self.searcher {
|
|
|
|
Naive(ref mut searcher)
|
|
|
|
=> searcher.next(self.haystack.as_bytes(), self.needle.as_bytes()),
|
|
|
|
TwoWay(ref mut searcher)
|
|
|
|
=> searcher.next(self.haystack.as_bytes(), self.needle.as_bytes(), false),
|
|
|
|
TwoWayLong(ref mut searcher)
|
2014-12-30 21:54:17 +01:00
|
|
|
=> searcher.next(self.haystack.as_bytes(), self.needle.as_bytes(), true),
|
|
|
|
Searcher::EmptyNeedle { ref mut pos, ref mut done } => {
|
|
|
|
if !*done {
|
|
|
|
let r = Some((*pos, *pos));
|
|
|
|
if *pos == self.haystack.len() {
|
|
|
|
*done = true;
|
|
|
|
} else {
|
|
|
|
use char::CharExt;
|
|
|
|
*pos += self.haystack.char_at(*pos).len_utf8();
|
|
|
|
}
|
|
|
|
r
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a> Iterator for SplitStr<'a> {
|
|
|
|
type Item = &'a str;
|
|
|
|
|
2014-04-30 23:06:36 -07:00
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<&'a str> {
|
|
|
|
if self.finished { return None; }
|
|
|
|
|
|
|
|
match self.it.next() {
|
|
|
|
Some((from, to)) => {
|
2015-01-17 16:15:47 -08:00
|
|
|
let ret = Some(&self.it.haystack[self.last_end .. from]);
|
2014-04-30 23:06:36 -07:00
|
|
|
self.last_end = to;
|
|
|
|
ret
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
self.finished = true;
|
2015-01-17 16:15:47 -08:00
|
|
|
Some(&self.it.haystack[self.last_end .. self.it.haystack.len()])
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-19 12:44:24 +13:00
|
|
|
|
2014-04-30 23:06:36 -07:00
|
|
|
/*
|
|
|
|
Section: Comparing strings
|
|
|
|
*/
|
|
|
|
|
|
|
|
// share the implementation of the lang-item vs. non-lang-item
|
|
|
|
// eq_slice.
|
2014-06-07 15:32:01 +01:00
|
|
|
/// NOTE: This function is (ab)used in rustc::middle::trans::_match
|
|
|
|
/// to compare &[u8] byte slices that are not necessarily valid UTF-8.
|
2014-04-30 23:06:36 -07:00
|
|
|
#[inline]
|
|
|
|
fn eq_slice_(a: &str, b: &str) -> bool {
|
2015-02-15 00:09:40 +03:00
|
|
|
// NOTE: In theory n should be libc::size_t and not usize, but libc is not available here
|
2014-10-27 15:37:07 -07:00
|
|
|
#[allow(improper_ctypes)]
|
2014-12-30 21:54:17 +01:00
|
|
|
extern { fn memcmp(s1: *const i8, s2: *const i8, n: uint) -> i32; }
|
2014-04-30 23:06:36 -07:00
|
|
|
a.len() == b.len() && unsafe {
|
2014-06-25 12:47:34 -07:00
|
|
|
memcmp(a.as_ptr() as *const i8,
|
|
|
|
b.as_ptr() as *const i8,
|
2014-04-30 23:06:36 -07:00
|
|
|
a.len()) == 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Bytewise slice equality
|
2014-06-07 15:32:01 +01:00
|
|
|
/// NOTE: This function is (ab)used in rustc::middle::trans::_match
|
|
|
|
/// to compare &[u8] byte slices that are not necessarily valid UTF-8.
|
2014-04-30 23:06:36 -07:00
|
|
|
#[lang="str_eq"]
|
|
|
|
#[inline]
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
fn eq_slice(a: &str, b: &str) -> bool {
|
2014-04-30 23:06:36 -07:00
|
|
|
eq_slice_(a, b)
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Section: Misc
|
|
|
|
*/
|
|
|
|
|
|
|
|
/// Walk through `iter` checking that it's a valid UTF-8 sequence,
|
|
|
|
/// returning `true` in that case, or, if it is invalid, `false` with
|
|
|
|
/// `iter` reset such that it is pointing at the first byte in the
|
|
|
|
/// invalid sequence.
|
|
|
|
#[inline(always)]
|
2014-12-22 12:49:57 -08:00
|
|
|
fn run_utf8_validation_iterator(iter: &mut slice::Iter<u8>)
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
-> Result<(), Utf8Error> {
|
|
|
|
let whole = iter.as_slice();
|
2014-04-30 23:06:36 -07:00
|
|
|
loop {
|
|
|
|
// save the current thing we're pointing at.
|
2015-01-23 10:54:32 -05:00
|
|
|
let old = iter.clone();
|
2014-04-30 23:06:36 -07:00
|
|
|
|
|
|
|
// restore the iterator we had at the start of this codepoint.
|
2015-01-02 14:44:21 -08:00
|
|
|
macro_rules! err { () => {{
|
2015-01-23 10:54:32 -05:00
|
|
|
*iter = old.clone();
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
return Err(Utf8Error::InvalidByte(whole.len() - iter.as_slice().len()))
|
2015-01-02 14:44:21 -08:00
|
|
|
}}}
|
|
|
|
|
|
|
|
macro_rules! next { () => {
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
match iter.next() {
|
|
|
|
Some(a) => *a,
|
|
|
|
// we needed data, but there was none: error!
|
|
|
|
None => return Err(Utf8Error::TooShort),
|
|
|
|
}
|
2015-01-02 14:44:21 -08:00
|
|
|
}}
|
2014-04-30 23:06:36 -07:00
|
|
|
|
|
|
|
let first = match iter.next() {
|
|
|
|
Some(&b) => b,
|
|
|
|
// we're at the end of the iterator and a codepoint
|
|
|
|
// boundary at the same time, so this string is valid.
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
None => return Ok(())
|
2014-04-30 23:06:36 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
// ASCII characters are always valid, so only large
|
|
|
|
// bytes need more examination.
|
|
|
|
if first >= 128 {
|
2014-12-30 21:54:17 +01:00
|
|
|
let w = UTF8_CHAR_WIDTH[first as uint] as uint;
|
2014-04-30 23:06:36 -07:00
|
|
|
let second = next!();
|
2014-12-09 14:08:10 -08:00
|
|
|
// 2-byte encoding is for codepoints \u{0080} to \u{07ff}
|
2014-04-30 23:06:36 -07:00
|
|
|
// first C2 80 last DF BF
|
2014-12-09 14:08:10 -08:00
|
|
|
// 3-byte encoding is for codepoints \u{0800} to \u{ffff}
|
2014-04-30 23:06:36 -07:00
|
|
|
// first E0 A0 80 last EF BF BF
|
2014-12-09 14:08:10 -08:00
|
|
|
// excluding surrogates codepoints \u{d800} to \u{dfff}
|
2014-04-30 23:06:36 -07:00
|
|
|
// ED A0 80 to ED BF BF
|
2014-12-09 14:08:10 -08:00
|
|
|
// 4-byte encoding is for codepoints \u{1000}0 to \u{10ff}ff
|
2014-04-30 23:06:36 -07:00
|
|
|
// first F0 90 80 80 last F4 8F BF BF
|
|
|
|
//
|
|
|
|
// Use the UTF-8 syntax from the RFC
|
|
|
|
//
|
|
|
|
// https://tools.ietf.org/html/rfc3629
|
|
|
|
// UTF8-1 = %x00-7F
|
|
|
|
// UTF8-2 = %xC2-DF UTF8-tail
|
|
|
|
// UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
|
|
|
|
// %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
|
|
|
|
// UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
|
|
|
|
// %xF4 %x80-8F 2( UTF8-tail )
|
|
|
|
match w {
|
2014-07-18 00:59:49 +02:00
|
|
|
2 => if second & !CONT_MASK != TAG_CONT_U8 {err!()},
|
2014-04-30 23:06:36 -07:00
|
|
|
3 => {
|
2014-07-18 00:59:49 +02:00
|
|
|
match (first, second, next!() & !CONT_MASK) {
|
2014-09-26 21:13:20 -07:00
|
|
|
(0xE0 , 0xA0 ... 0xBF, TAG_CONT_U8) |
|
|
|
|
(0xE1 ... 0xEC, 0x80 ... 0xBF, TAG_CONT_U8) |
|
|
|
|
(0xED , 0x80 ... 0x9F, TAG_CONT_U8) |
|
|
|
|
(0xEE ... 0xEF, 0x80 ... 0xBF, TAG_CONT_U8) => {}
|
2014-04-30 23:06:36 -07:00
|
|
|
_ => err!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
4 => {
|
2014-07-18 00:59:49 +02:00
|
|
|
match (first, second, next!() & !CONT_MASK, next!() & !CONT_MASK) {
|
2014-09-26 21:13:20 -07:00
|
|
|
(0xF0 , 0x90 ... 0xBF, TAG_CONT_U8, TAG_CONT_U8) |
|
|
|
|
(0xF1 ... 0xF3, 0x80 ... 0xBF, TAG_CONT_U8, TAG_CONT_U8) |
|
|
|
|
(0xF4 , 0x80 ... 0x8F, TAG_CONT_U8, TAG_CONT_U8) => {}
|
2014-04-30 23:06:36 -07:00
|
|
|
_ => err!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => err!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// https://tools.ietf.org/html/rfc3629
|
2014-12-30 21:19:41 +13:00
|
|
|
static UTF8_CHAR_WIDTH: [u8; 256] = [
|
2014-04-30 23:06:36 -07:00
|
|
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
|
|
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F
|
|
|
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
|
|
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3F
|
|
|
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
|
|
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5F
|
|
|
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
|
|
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7F
|
|
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9F
|
|
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBF
|
|
|
|
0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
|
|
|
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDF
|
|
|
|
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEF
|
|
|
|
4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF
|
|
|
|
];
|
|
|
|
|
|
|
|
/// Struct that contains a `char` and the index of the first byte of
|
|
|
|
/// the next `char` in a string. This can be used as a data structure
|
|
|
|
/// for iterating over the UTF-8 bytes of a string.
|
2015-01-03 22:54:18 -05:00
|
|
|
#[derive(Copy)]
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "naming is uncertain with container conventions")]
|
2014-04-30 23:06:36 -07:00
|
|
|
pub struct CharRange {
|
|
|
|
/// Current `char`
|
|
|
|
pub ch: char,
|
|
|
|
/// Index of the first byte of the next `char`
|
2014-12-30 21:54:17 +01:00
|
|
|
pub next: uint,
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
2014-07-18 00:59:49 +02:00
|
|
|
/// Mask of the value bits of a continuation byte
|
2014-10-06 16:14:00 -07:00
|
|
|
const CONT_MASK: u8 = 0b0011_1111u8;
|
2014-07-18 00:59:49 +02:00
|
|
|
/// Value of the tag bits (tag mask is !CONT_MASK) of a continuation byte
|
2014-10-06 16:14:00 -07:00
|
|
|
const TAG_CONT_U8: u8 = 0b1000_0000u8;
|
2014-04-30 23:06:36 -07:00
|
|
|
|
|
|
|
/*
|
|
|
|
Section: Trait implementations
|
|
|
|
*/
|
|
|
|
|
2015-01-04 23:32:20 -08:00
|
|
|
mod traits {
|
2015-01-01 23:53:35 -08:00
|
|
|
use cmp::{Ordering, Ord, PartialEq, PartialOrd, Eq};
|
2014-11-28 11:57:41 -05:00
|
|
|
use cmp::Ordering::{Less, Equal, Greater};
|
2014-11-06 09:32:37 -08:00
|
|
|
use iter::IteratorExt;
|
2014-11-28 11:57:41 -05:00
|
|
|
use option::Option;
|
|
|
|
use option::Option::Some;
|
2014-09-26 21:46:22 -07:00
|
|
|
use ops;
|
2015-01-01 23:53:35 -08:00
|
|
|
use str::{StrExt, eq_slice};
|
2014-04-30 23:06:36 -07:00
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-10-29 20:11:16 -05:00
|
|
|
impl Ord for str {
|
|
|
|
#[inline]
|
|
|
|
fn cmp(&self, other: &str) -> Ordering {
|
|
|
|
for (s_b, o_b) in self.bytes().zip(other.bytes()) {
|
|
|
|
match s_b.cmp(&o_b) {
|
|
|
|
Greater => return Greater,
|
|
|
|
Less => return Less,
|
|
|
|
Equal => ()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
self.len().cmp(&other.len())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-10-29 20:11:16 -05:00
|
|
|
impl PartialEq for str {
|
|
|
|
#[inline]
|
|
|
|
fn eq(&self, other: &str) -> bool {
|
|
|
|
eq_slice(self, other)
|
|
|
|
}
|
|
|
|
#[inline]
|
|
|
|
fn ne(&self, other: &str) -> bool { !(*self).eq(other) }
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-10-29 20:11:16 -05:00
|
|
|
impl Eq for str {}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-10-29 20:11:16 -05:00
|
|
|
impl PartialOrd for str {
|
|
|
|
#[inline]
|
|
|
|
fn partial_cmp(&self, other: &str) -> Option<Ordering> {
|
|
|
|
Some(self.cmp(other))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-17 16:15:47 -08:00
|
|
|
/// Returns a slice of the given string from the byte range
|
|
|
|
/// [`begin`..`end`).
|
|
|
|
///
|
|
|
|
/// This operation is `O(1)`.
|
|
|
|
///
|
|
|
|
/// Panics when `begin` and `end` do not point to valid characters
|
|
|
|
/// or point beyond the last character of the string.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// let s = "Löwe 老虎 Léopard";
|
|
|
|
/// assert_eq!(&s[0 .. 1], "L");
|
|
|
|
///
|
|
|
|
/// assert_eq!(&s[1 .. 9], "öwe 老");
|
|
|
|
///
|
|
|
|
/// // these will panic:
|
|
|
|
/// // byte 2 lies within `ö`:
|
|
|
|
/// // &s[2 ..3];
|
|
|
|
///
|
|
|
|
/// // byte 8 lies within `老`
|
|
|
|
/// // &s[1 .. 8];
|
|
|
|
///
|
|
|
|
/// // byte 100 is outside the string
|
|
|
|
/// // &s[3 .. 100];
|
|
|
|
/// ```
|
2015-01-24 09:15:42 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-30 21:54:17 +01:00
|
|
|
impl ops::Index<ops::Range<uint>> for str {
|
2015-01-04 17:43:24 +13:00
|
|
|
type Output = str;
|
2014-10-05 11:59:10 +13:00
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn index(&self, index: &ops::Range<uint>) -> &str {
|
2015-01-17 16:15:47 -08:00
|
|
|
// is_char_boundary checks that the index is in [0, .len()]
|
|
|
|
if index.start <= index.end &&
|
|
|
|
self.is_char_boundary(index.start) &&
|
|
|
|
self.is_char_boundary(index.end) {
|
|
|
|
unsafe { self.slice_unchecked(index.start, index.end) }
|
|
|
|
} else {
|
|
|
|
super::slice_error_fail(self, index.start, index.end)
|
|
|
|
}
|
2014-10-05 11:59:10 +13:00
|
|
|
}
|
2014-12-31 20:20:40 +13:00
|
|
|
}
|
2015-01-17 16:15:47 -08:00
|
|
|
|
|
|
|
/// Returns a slice of the string from the beginning to byte
|
|
|
|
/// `end`.
|
|
|
|
///
|
|
|
|
/// Equivalent to `self[0 .. end]`.
|
|
|
|
///
|
|
|
|
/// Panics when `end` does not point to a valid character, or is
|
|
|
|
/// out of bounds.
|
2015-01-24 09:15:42 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-30 21:54:17 +01:00
|
|
|
impl ops::Index<ops::RangeTo<uint>> for str {
|
2015-01-04 17:43:24 +13:00
|
|
|
type Output = str;
|
2014-10-05 11:59:10 +13:00
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn index(&self, index: &ops::RangeTo<uint>) -> &str {
|
2015-01-17 16:15:47 -08:00
|
|
|
// is_char_boundary checks that the index is in [0, .len()]
|
|
|
|
if self.is_char_boundary(index.end) {
|
|
|
|
unsafe { self.slice_unchecked(0, index.end) }
|
|
|
|
} else {
|
|
|
|
super::slice_error_fail(self, 0, index.end)
|
|
|
|
}
|
2014-10-05 11:59:10 +13:00
|
|
|
}
|
2014-12-31 20:20:40 +13:00
|
|
|
}
|
2015-01-17 16:15:47 -08:00
|
|
|
|
|
|
|
/// Returns a slice of the string from `begin` to its end.
|
|
|
|
///
|
|
|
|
/// Equivalent to `self[begin .. self.len()]`.
|
|
|
|
///
|
|
|
|
/// Panics when `begin` does not point to a valid character, or is
|
|
|
|
/// out of bounds.
|
2015-01-24 09:15:42 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-30 21:54:17 +01:00
|
|
|
impl ops::Index<ops::RangeFrom<uint>> for str {
|
2015-01-04 17:43:24 +13:00
|
|
|
type Output = str;
|
2014-10-05 11:59:10 +13:00
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn index(&self, index: &ops::RangeFrom<uint>) -> &str {
|
2015-01-17 16:15:47 -08:00
|
|
|
// is_char_boundary checks that the index is in [0, .len()]
|
|
|
|
if self.is_char_boundary(index.start) {
|
|
|
|
unsafe { self.slice_unchecked(index.start, self.len()) }
|
|
|
|
} else {
|
|
|
|
super::slice_error_fail(self, index.start, self.len())
|
|
|
|
}
|
2014-10-05 11:59:10 +13:00
|
|
|
}
|
2014-12-31 20:20:40 +13:00
|
|
|
}
|
2015-01-17 16:15:47 -08:00
|
|
|
|
2015-01-28 17:06:46 +13:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
impl ops::Index<ops::RangeFull> for str {
|
|
|
|
type Output = str;
|
|
|
|
#[inline]
|
|
|
|
fn index(&self, _index: &ops::RangeFull) -> &str {
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Any string that can be represented as a slice
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "Instead of taking this bound generically, this trait will be \
|
2015-02-18 14:48:57 -05:00
|
|
|
replaced with one of slicing syntax (&foo[..]), deref coercions, or \
|
2015-01-12 18:40:19 -08:00
|
|
|
a more generic conversion trait")]
|
2015-01-04 21:39:02 -05:00
|
|
|
pub trait Str {
|
2014-04-30 23:06:36 -07:00
|
|
|
/// Work with `self` as a slice.
|
|
|
|
fn as_slice<'a>(&'a self) -> &'a str;
|
|
|
|
}
|
|
|
|
|
2014-11-23 13:13:17 -05:00
|
|
|
impl Str for str {
|
2014-04-30 23:06:36 -07:00
|
|
|
#[inline]
|
2014-11-23 13:13:17 -05:00
|
|
|
fn as_slice<'a>(&'a self) -> &'a str { self }
|
|
|
|
}
|
|
|
|
|
2015-01-06 10:16:49 +13:00
|
|
|
impl<'a, S: ?Sized> Str for &'a S where S: Str {
|
2014-11-23 13:13:17 -05:00
|
|
|
#[inline]
|
|
|
|
fn as_slice(&self) -> &str { Str::as_slice(*self) }
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
2014-12-18 02:12:53 +01:00
|
|
|
/// Return type of `StrExt::split`
|
2015-01-03 22:54:18 -05:00
|
|
|
#[derive(Clone)]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-18 02:12:53 +01:00
|
|
|
pub struct Split<'a, P>(CharSplits<'a, P>);
|
2015-01-05 01:51:03 -05:00
|
|
|
delegate_iter!{pattern &'a str : Split<'a, P>}
|
2014-12-18 02:12:53 +01:00
|
|
|
|
|
|
|
/// Return type of `StrExt::split_terminator`
|
2015-01-03 22:54:18 -05:00
|
|
|
#[derive(Clone)]
|
2015-01-22 18:22:03 -08:00
|
|
|
#[unstable(feature = "core",
|
2015-01-12 18:40:19 -08:00
|
|
|
reason = "might get removed in favour of a constructor method on Split")]
|
2014-12-18 02:12:53 +01:00
|
|
|
pub struct SplitTerminator<'a, P>(CharSplits<'a, P>);
|
2015-01-05 01:51:03 -05:00
|
|
|
delegate_iter!{pattern &'a str : SplitTerminator<'a, P>}
|
2014-12-18 02:12:53 +01:00
|
|
|
|
|
|
|
/// Return type of `StrExt::splitn`
|
2015-01-03 22:54:18 -05:00
|
|
|
#[derive(Clone)]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-18 02:12:53 +01:00
|
|
|
pub struct SplitN<'a, P>(CharSplitsN<'a, P>);
|
2015-01-05 01:51:03 -05:00
|
|
|
delegate_iter!{pattern forward &'a str : SplitN<'a, P>}
|
2014-12-18 02:12:53 +01:00
|
|
|
|
|
|
|
/// Return type of `StrExt::rsplitn`
|
2015-01-03 22:54:18 -05:00
|
|
|
#[derive(Clone)]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-18 02:12:53 +01:00
|
|
|
pub struct RSplitN<'a, P>(CharSplitsN<'a, P>);
|
2015-01-05 01:51:03 -05:00
|
|
|
delegate_iter!{pattern forward &'a str : RSplitN<'a, P>}
|
2014-12-18 02:12:53 +01:00
|
|
|
|
2014-04-30 23:06:36 -07:00
|
|
|
/// Methods for string slices
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
#[allow(missing_docs)]
|
2015-01-04 21:39:02 -05:00
|
|
|
pub trait StrExt {
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
// NB there are no docs here are they're all located on the StrExt trait in
|
|
|
|
// libcollections, not here.
|
2014-04-30 23:06:36 -07:00
|
|
|
|
2014-12-30 21:54:17 +01:00
|
|
|
fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool;
|
|
|
|
fn contains_char<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool;
|
2014-10-23 10:43:18 -05:00
|
|
|
fn chars<'a>(&'a self) -> Chars<'a>;
|
|
|
|
fn bytes<'a>(&'a self) -> Bytes<'a>;
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
fn char_indices<'a>(&'a self) -> CharIndices<'a>;
|
2014-12-18 02:12:53 +01:00
|
|
|
fn split<'a, P: CharEq>(&'a self, pat: P) -> Split<'a, P>;
|
2014-12-30 21:54:17 +01:00
|
|
|
fn splitn<'a, P: CharEq>(&'a self, count: uint, pat: P) -> SplitN<'a, P>;
|
2014-12-18 02:12:53 +01:00
|
|
|
fn split_terminator<'a, P: CharEq>(&'a self, pat: P) -> SplitTerminator<'a, P>;
|
2014-12-30 21:54:17 +01:00
|
|
|
fn rsplitn<'a, P: CharEq>(&'a self, count: uint, pat: P) -> RSplitN<'a, P>;
|
2014-10-23 10:43:18 -05:00
|
|
|
fn match_indices<'a>(&'a self, sep: &'a str) -> MatchIndices<'a>;
|
2014-12-18 02:12:53 +01:00
|
|
|
fn split_str<'a>(&'a self, pat: &'a str) -> SplitStr<'a>;
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
fn lines<'a>(&'a self) -> Lines<'a>;
|
|
|
|
fn lines_any<'a>(&'a self) -> LinesAny<'a>;
|
2014-12-30 21:54:17 +01:00
|
|
|
fn char_len(&self) -> uint;
|
|
|
|
fn slice_chars<'a>(&'a self, begin: uint, end: uint) -> &'a str;
|
|
|
|
unsafe fn slice_unchecked<'a>(&'a self, begin: uint, end: uint) -> &'a str;
|
2014-12-18 02:12:53 +01:00
|
|
|
fn starts_with(&self, pat: &str) -> bool;
|
|
|
|
fn ends_with(&self, pat: &str) -> bool;
|
2014-12-30 21:54:17 +01:00
|
|
|
fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
|
|
|
|
where P::Matcher: DoubleEndedMatcher<'a>;
|
|
|
|
fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str;
|
|
|
|
fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
|
|
|
|
where P::Matcher: ReverseMatcher<'a>;
|
|
|
|
fn is_char_boundary(&self, index: uint) -> bool;
|
|
|
|
fn char_range_at(&self, start: uint) -> CharRange;
|
|
|
|
fn char_range_at_reverse(&self, start: uint) -> CharRange;
|
|
|
|
fn char_at(&self, i: uint) -> char;
|
|
|
|
fn char_at_reverse(&self, i: uint) -> char;
|
2014-10-23 10:43:18 -05:00
|
|
|
fn as_bytes<'a>(&'a self) -> &'a [u8];
|
2014-12-30 21:54:17 +01:00
|
|
|
fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<uint>;
|
|
|
|
fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<uint>
|
|
|
|
where P::Matcher: ReverseMatcher<'a>;
|
|
|
|
fn find_str(&self, pat: &str) -> Option<uint>;
|
change return type of slice_shift_char
`slice_shift_char` splits a `str` into it's leading `char` and the remainder
of the `str`. Currently, it returns a `(Option<char>, &str)` such that:
"bar".slice_shift_char() => (Some('b'), "ar")
"ar".slice_shift_char() => (Some('a'), "r")
"r".slice_shift_char() => (Some('r'), "")
"".slice_shift_char() => (None, "")
This is a little odd. Either a `str` can be split into both a head and a
tail or it cannot. So the return type should be `Option<(char, &str)>`.
With the current behaviour, in the case of the empty string, the `str`
returned is meaningless - it is always the empty string.
This commit changes slice_shift_char so that:
"bar".slice_shift_char() => Some(('b', "ar"))
"ar".slice_shift_char() => Some(('a', "r"))
"r".slice_shift_char() => Some(('r', ""))
"".slice_shift_char() => None
[breaking-change]
2014-11-17 17:35:18 +08:00
|
|
|
fn slice_shift_char<'a>(&'a self) -> Option<(char, &'a str)>;
|
2014-12-30 21:54:17 +01:00
|
|
|
fn subslice_offset(&self, inner: &str) -> uint;
|
2014-06-25 12:47:34 -07:00
|
|
|
fn as_ptr(&self) -> *const u8;
|
2014-12-30 21:54:17 +01:00
|
|
|
fn len(&self) -> uint;
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
fn is_empty(&self) -> bool;
|
2015-01-27 22:52:32 -08:00
|
|
|
fn parse<T: FromStr>(&self) -> Result<T, T::Err>;
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
2014-08-23 12:30:08 +02:00
|
|
|
#[inline(never)]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn slice_error_fail(s: &str, begin: uint, end: uint) -> ! {
|
2014-08-23 12:30:08 +02:00
|
|
|
assert!(begin <= end);
|
2014-10-09 15:17:22 -04:00
|
|
|
panic!("index {} and/or {} in `{}` do not lie on character boundary",
|
2014-08-23 12:30:08 +02:00
|
|
|
begin, end, s);
|
|
|
|
}
|
|
|
|
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
impl StrExt for str {
|
2014-04-30 23:06:36 -07:00
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
|
|
|
|
pat.is_contained_in(self)
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn contains_char<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
|
|
|
|
pat.is_contained_in(self)
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn chars(&self) -> Chars {
|
2014-07-17 19:34:07 +02:00
|
|
|
Chars{iter: self.as_bytes().iter()}
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn bytes(&self) -> Bytes {
|
2014-12-18 02:12:53 +01:00
|
|
|
Bytes(self.as_bytes().iter().map(BytesDeref))
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
fn char_indices(&self) -> CharIndices {
|
|
|
|
CharIndices { front_offset: 0, iter: self.chars() }
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-18 02:12:53 +01:00
|
|
|
fn split<P: CharEq>(&self, pat: P) -> Split<P> {
|
|
|
|
Split(CharSplits {
|
2014-10-23 10:43:18 -05:00
|
|
|
string: self,
|
2014-12-18 02:12:53 +01:00
|
|
|
only_ascii: pat.only_ascii(),
|
|
|
|
sep: pat,
|
2014-04-30 23:06:36 -07:00
|
|
|
allow_trailing_empty: true,
|
|
|
|
finished: false,
|
2014-12-18 02:12:53 +01:00
|
|
|
})
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn splitn<P: CharEq>(&self, count: uint, pat: P) -> SplitN<P> {
|
2014-12-18 02:12:53 +01:00
|
|
|
SplitN(CharSplitsN {
|
|
|
|
iter: self.split(pat).0,
|
2014-04-30 23:06:36 -07:00
|
|
|
count: count,
|
|
|
|
invert: false,
|
2014-12-18 02:12:53 +01:00
|
|
|
})
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-18 02:12:53 +01:00
|
|
|
fn split_terminator<P: CharEq>(&self, pat: P) -> SplitTerminator<P> {
|
|
|
|
SplitTerminator(CharSplits {
|
2014-04-30 23:06:36 -07:00
|
|
|
allow_trailing_empty: false,
|
2014-12-18 02:12:53 +01:00
|
|
|
..self.split(pat).0
|
|
|
|
})
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn rsplitn<P: CharEq>(&self, count: uint, pat: P) -> RSplitN<P> {
|
2014-12-18 02:12:53 +01:00
|
|
|
RSplitN(CharSplitsN {
|
|
|
|
iter: self.split(pat).0,
|
2014-04-30 23:06:36 -07:00
|
|
|
count: count,
|
|
|
|
invert: true,
|
2014-12-18 02:12:53 +01:00
|
|
|
})
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn match_indices<'a>(&'a self, sep: &'a str) -> MatchIndices<'a> {
|
2014-04-30 23:06:36 -07:00
|
|
|
MatchIndices {
|
2014-10-23 10:43:18 -05:00
|
|
|
haystack: self,
|
2014-04-30 23:06:36 -07:00
|
|
|
needle: sep,
|
2014-05-11 19:34:33 -05:00
|
|
|
searcher: Searcher::new(self.as_bytes(), sep.as_bytes())
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-18 02:12:53 +01:00
|
|
|
fn split_str<'a>(&'a self, sep: &'a str) -> SplitStr<'a> {
|
|
|
|
SplitStr {
|
2014-04-30 23:06:36 -07:00
|
|
|
it: self.match_indices(sep),
|
|
|
|
last_end: 0,
|
|
|
|
finished: false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
fn lines(&self) -> Lines {
|
2014-12-18 02:12:53 +01:00
|
|
|
Lines { inner: self.split_terminator('\n').0 }
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
fn lines_any(&self) -> LinesAny {
|
2014-12-02 13:59:08 -05:00
|
|
|
fn f(line: &str) -> &str {
|
2014-04-30 23:06:36 -07:00
|
|
|
let l = line.len();
|
2015-01-17 16:15:47 -08:00
|
|
|
if l > 0 && line.as_bytes()[l - 1] == b'\r' { &line[0 .. l - 1] }
|
2014-04-30 23:06:36 -07:00
|
|
|
else { line }
|
2014-12-02 13:59:08 -05:00
|
|
|
}
|
|
|
|
|
2014-12-15 15:41:30 -05:00
|
|
|
let f: fn(&str) -> &str = f; // coerce to fn pointer
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
LinesAny { inner: self.lines().map(f) }
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn char_len(&self) -> uint { self.chars().count() }
|
2014-04-30 23:06:36 -07:00
|
|
|
|
2014-12-30 21:54:17 +01:00
|
|
|
fn slice_chars(&self, begin: uint, end: uint) -> &str {
|
2014-04-30 23:06:36 -07:00
|
|
|
assert!(begin <= end);
|
|
|
|
let mut count = 0;
|
|
|
|
let mut begin_byte = None;
|
|
|
|
let mut end_byte = None;
|
|
|
|
|
|
|
|
// This could be even more efficient by not decoding,
|
|
|
|
// only finding the char boundaries
|
|
|
|
for (idx, _) in self.char_indices() {
|
|
|
|
if count == begin { begin_byte = Some(idx); }
|
|
|
|
if count == end { end_byte = Some(idx); break; }
|
|
|
|
count += 1;
|
|
|
|
}
|
|
|
|
if begin_byte.is_none() && count == begin { begin_byte = Some(self.len()) }
|
|
|
|
if end_byte.is_none() && count == end { end_byte = Some(self.len()) }
|
|
|
|
|
|
|
|
match (begin_byte, end_byte) {
|
2014-10-09 15:17:22 -04:00
|
|
|
(None, _) => panic!("slice_chars: `begin` is beyond end of string"),
|
|
|
|
(_, None) => panic!("slice_chars: `end` is beyond end of string"),
|
2014-11-20 10:11:15 -08:00
|
|
|
(Some(a), Some(b)) => unsafe { self.slice_unchecked(a, b) }
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-20 10:11:15 -08:00
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
unsafe fn slice_unchecked(&self, begin: uint, end: uint) -> &str {
|
2014-11-20 10:11:15 -08:00
|
|
|
mem::transmute(Slice {
|
2014-12-30 21:54:17 +01:00
|
|
|
data: self.as_ptr().offset(begin as int),
|
2014-11-20 10:11:15 -08:00
|
|
|
len: end - begin,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2014-04-30 23:06:36 -07:00
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn starts_with(&self, needle: &str) -> bool {
|
2014-04-30 23:06:36 -07:00
|
|
|
let n = needle.len();
|
2015-01-12 16:59:18 -05:00
|
|
|
self.len() >= n && needle.as_bytes() == &self.as_bytes()[..n]
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn ends_with(&self, needle: &str) -> bool {
|
|
|
|
let (m, n) = (self.len(), needle.len());
|
2015-01-19 11:07:13 -05:00
|
|
|
m >= n && needle.as_bytes() == &self.as_bytes()[m-n..]
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
|
|
|
|
where P::Matcher: DoubleEndedMatcher<'a> {
|
|
|
|
let mut i = 0;
|
|
|
|
let mut matcher = pat.into_matcher(self);
|
|
|
|
let mut possible_end_match = None;
|
|
|
|
while let Some((a, b)) = Matcher::next(&mut matcher) {
|
|
|
|
if a == i {
|
|
|
|
i = b;
|
|
|
|
} else {
|
|
|
|
possible_end_match = Some((a, b));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let mut j = self.len();
|
|
|
|
while let Some((a, b)) = ReverseMatcher::next_back(&mut matcher)
|
|
|
|
.or_else(|| possible_end_match.take()) {
|
|
|
|
if b == j {
|
|
|
|
j = a;
|
|
|
|
} else {
|
|
|
|
break;
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
}
|
2014-12-30 21:54:17 +01:00
|
|
|
unsafe {
|
|
|
|
// Matcher is known to return valid indices
|
|
|
|
self.slice_unchecked(i, j)
|
|
|
|
}
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &str {
|
|
|
|
let mut i = 0;
|
|
|
|
let mut matcher = pat.into_matcher(self);
|
|
|
|
while let Some((a, b)) = Matcher::next(&mut matcher) {
|
|
|
|
if a == i {
|
|
|
|
i = b;
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
unsafe {
|
|
|
|
// Matcher is known to return valid indices
|
|
|
|
self.slice_unchecked(i, self.len())
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &str
|
|
|
|
where P::Matcher: ReverseMatcher<'a> {
|
|
|
|
let mut i = self.len();
|
|
|
|
let mut matcher = pat.into_matcher(self);
|
|
|
|
while let Some((a, b)) = ReverseMatcher::next_back(&mut matcher) {
|
|
|
|
if b == i {
|
|
|
|
i = a;
|
|
|
|
} else {
|
|
|
|
break;
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
}
|
2014-12-30 21:54:17 +01:00
|
|
|
unsafe {
|
|
|
|
// Matcher is known to return valid indices
|
|
|
|
self.slice_unchecked(0, i)
|
|
|
|
}
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn is_char_boundary(&self, index: uint) -> bool {
|
2014-04-30 23:06:36 -07:00
|
|
|
if index == self.len() { return true; }
|
2014-08-23 12:30:08 +02:00
|
|
|
match self.as_bytes().get(index) {
|
|
|
|
None => false,
|
|
|
|
Some(&b) => b < 128u8 || b >= 192u8,
|
|
|
|
}
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn char_range_at(&self, i: uint) -> CharRange {
|
2015-01-21 15:55:31 -08:00
|
|
|
let (c, n) = char_range_at_raw(self.as_bytes(), i);
|
|
|
|
CharRange { ch: unsafe { mem::transmute(c) }, next: n }
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn char_range_at_reverse(&self, start: uint) -> CharRange {
|
2014-04-30 23:06:36 -07:00
|
|
|
let mut prev = start;
|
|
|
|
|
|
|
|
prev = prev.saturating_sub(1);
|
2014-06-19 18:22:33 -07:00
|
|
|
if self.as_bytes()[prev] < 128 {
|
|
|
|
return CharRange{ch: self.as_bytes()[prev] as char, next: prev}
|
|
|
|
}
|
2014-04-30 23:06:36 -07:00
|
|
|
|
|
|
|
// Multibyte case is a fn to allow char_range_at_reverse to inline cleanly
|
2014-12-30 21:54:17 +01:00
|
|
|
fn multibyte_char_range_at_reverse(s: &str, mut i: uint) -> CharRange {
|
2014-04-30 23:06:36 -07:00
|
|
|
// while there is a previous byte == 10......
|
2014-07-18 00:59:49 +02:00
|
|
|
while i > 0 && s.as_bytes()[i] & !CONT_MASK == TAG_CONT_U8 {
|
2015-01-22 14:08:56 +00:00
|
|
|
i -= 1;
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
2014-06-19 18:22:33 -07:00
|
|
|
let mut val = s.as_bytes()[i] as u32;
|
2014-12-30 21:54:17 +01:00
|
|
|
let w = UTF8_CHAR_WIDTH[val as uint] as uint;
|
2014-04-30 23:06:36 -07:00
|
|
|
assert!((w != 0));
|
|
|
|
|
|
|
|
val = utf8_first_byte!(val, w);
|
2014-06-19 18:22:33 -07:00
|
|
|
val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 1]);
|
|
|
|
if w > 2 { val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 2]); }
|
|
|
|
if w > 3 { val = utf8_acc_cont_byte!(val, s.as_bytes()[i + 3]); }
|
2014-04-30 23:06:36 -07:00
|
|
|
|
core: Remove the cast module
This commit revisits the `cast` module in libcore and libstd, and scrutinizes
all functions inside of it. The result was to remove the `cast` module entirely,
folding all functionality into the `mem` module. Specifically, this is the fate
of each function in the `cast` module.
* transmute - This function was moved to `mem`, but it is now marked as
#[unstable]. This is due to planned changes to the `transmute`
function and how it can be invoked (see the #[unstable] comment).
For more information, see RFC 5 and #12898
* transmute_copy - This function was moved to `mem`, with clarification that is
is not an error to invoke it with T/U that are different
sizes, but rather that it is strongly discouraged. This
function is now #[stable]
* forget - This function was moved to `mem` and marked #[stable]
* bump_box_refcount - This function was removed due to the deprecation of
managed boxes as well as its questionable utility.
* transmute_mut - This function was previously deprecated, and removed as part
of this commit.
* transmute_mut_unsafe - This function doesn't serve much of a purpose when it
can be achieved with an `as` in safe code, so it was
removed.
* transmute_lifetime - This function was removed because it is likely a strong
indication that code is incorrect in the first place.
* transmute_mut_lifetime - This function was removed for the same reasons as
`transmute_lifetime`
* copy_lifetime - This function was moved to `mem`, but it is marked
`#[unstable]` now due to the likelihood of being removed in
the future if it is found to not be very useful.
* copy_mut_lifetime - This function was also moved to `mem`, but had the same
treatment as `copy_lifetime`.
* copy_lifetime_vec - This function was removed because it is not used today,
and its existence is not necessary with DST
(copy_lifetime will suffice).
In summary, the cast module was stripped down to these functions, and then the
functions were moved to the `mem` module.
transmute - #[unstable]
transmute_copy - #[stable]
forget - #[stable]
copy_lifetime - #[unstable]
copy_mut_lifetime - #[unstable]
[breaking-change]
2014-05-09 10:34:51 -07:00
|
|
|
return CharRange {ch: unsafe { mem::transmute(val) }, next: i};
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
2014-10-23 10:43:18 -05:00
|
|
|
return multibyte_char_range_at_reverse(self, prev);
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn char_at(&self, i: uint) -> char {
|
2014-04-30 23:06:36 -07:00
|
|
|
self.char_range_at(i).ch
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn char_at_reverse(&self, i: uint) -> char {
|
2014-04-30 23:06:36 -07:00
|
|
|
self.char_range_at_reverse(i).ch
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-10-23 10:43:18 -05:00
|
|
|
fn as_bytes(&self) -> &[u8] {
|
|
|
|
unsafe { mem::transmute(self) }
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
2014-12-30 21:54:17 +01:00
|
|
|
fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<uint> {
|
|
|
|
Matcher::next(&mut pat.into_matcher(self)).map(|(i, _)| i)
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
2014-12-30 21:54:17 +01:00
|
|
|
fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<uint>
|
|
|
|
where P::Matcher: ReverseMatcher<'a> {
|
|
|
|
ReverseMatcher::next_back(&mut pat.into_matcher(self)).map(|(i, _)| i)
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
2014-12-30 21:54:17 +01:00
|
|
|
fn find_str(&self, needle: &str) -> Option<uint> {
|
2014-04-30 23:06:36 -07:00
|
|
|
if needle.is_empty() {
|
|
|
|
Some(0)
|
|
|
|
} else {
|
|
|
|
self.match_indices(needle)
|
|
|
|
.next()
|
|
|
|
.map(|(start, _end)| start)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
change return type of slice_shift_char
`slice_shift_char` splits a `str` into it's leading `char` and the remainder
of the `str`. Currently, it returns a `(Option<char>, &str)` such that:
"bar".slice_shift_char() => (Some('b'), "ar")
"ar".slice_shift_char() => (Some('a'), "r")
"r".slice_shift_char() => (Some('r'), "")
"".slice_shift_char() => (None, "")
This is a little odd. Either a `str` can be split into both a head and a
tail or it cannot. So the return type should be `Option<(char, &str)>`.
With the current behaviour, in the case of the empty string, the `str`
returned is meaningless - it is always the empty string.
This commit changes slice_shift_char so that:
"bar".slice_shift_char() => Some(('b', "ar"))
"ar".slice_shift_char() => Some(('a', "r"))
"r".slice_shift_char() => Some(('r', ""))
"".slice_shift_char() => None
[breaking-change]
2014-11-17 17:35:18 +08:00
|
|
|
fn slice_shift_char(&self) -> Option<(char, &str)> {
|
2014-04-30 23:06:36 -07:00
|
|
|
if self.is_empty() {
|
change return type of slice_shift_char
`slice_shift_char` splits a `str` into it's leading `char` and the remainder
of the `str`. Currently, it returns a `(Option<char>, &str)` such that:
"bar".slice_shift_char() => (Some('b'), "ar")
"ar".slice_shift_char() => (Some('a'), "r")
"r".slice_shift_char() => (Some('r'), "")
"".slice_shift_char() => (None, "")
This is a little odd. Either a `str` can be split into both a head and a
tail or it cannot. So the return type should be `Option<(char, &str)>`.
With the current behaviour, in the case of the empty string, the `str`
returned is meaningless - it is always the empty string.
This commit changes slice_shift_char so that:
"bar".slice_shift_char() => Some(('b', "ar"))
"ar".slice_shift_char() => Some(('a', "r"))
"r".slice_shift_char() => Some(('r', ""))
"".slice_shift_char() => None
[breaking-change]
2014-11-17 17:35:18 +08:00
|
|
|
None
|
2014-04-30 23:06:36 -07:00
|
|
|
} else {
|
2015-01-22 14:08:56 +00:00
|
|
|
let CharRange {ch, next} = self.char_range_at(0);
|
2014-11-20 10:11:15 -08:00
|
|
|
let next_s = unsafe { self.slice_unchecked(next, self.len()) };
|
change return type of slice_shift_char
`slice_shift_char` splits a `str` into it's leading `char` and the remainder
of the `str`. Currently, it returns a `(Option<char>, &str)` such that:
"bar".slice_shift_char() => (Some('b'), "ar")
"ar".slice_shift_char() => (Some('a'), "r")
"r".slice_shift_char() => (Some('r'), "")
"".slice_shift_char() => (None, "")
This is a little odd. Either a `str` can be split into both a head and a
tail or it cannot. So the return type should be `Option<(char, &str)>`.
With the current behaviour, in the case of the empty string, the `str`
returned is meaningless - it is always the empty string.
This commit changes slice_shift_char so that:
"bar".slice_shift_char() => Some(('b', "ar"))
"ar".slice_shift_char() => Some(('a', "r"))
"r".slice_shift_char() => Some(('r', ""))
"".slice_shift_char() => None
[breaking-change]
2014-11-17 17:35:18 +08:00
|
|
|
Some((ch, next_s))
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-30 21:54:17 +01:00
|
|
|
fn subslice_offset(&self, inner: &str) -> uint {
|
|
|
|
let a_start = self.as_ptr() as uint;
|
2014-04-30 23:06:36 -07:00
|
|
|
let a_end = a_start + self.len();
|
2014-12-30 21:54:17 +01:00
|
|
|
let b_start = inner.as_ptr() as uint;
|
2014-04-30 23:06:36 -07:00
|
|
|
let b_end = b_start + inner.len();
|
|
|
|
|
|
|
|
assert!(a_start <= b_start);
|
|
|
|
assert!(b_end <= a_end);
|
|
|
|
b_start - a_start
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
2014-06-25 12:47:34 -07:00
|
|
|
fn as_ptr(&self) -> *const u8 {
|
2014-04-30 23:06:36 -07:00
|
|
|
self.repr().data
|
|
|
|
}
|
2014-05-31 13:02:29 +02:00
|
|
|
|
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn len(&self) -> uint { self.repr().len }
|
2014-10-30 13:43:24 -07:00
|
|
|
|
|
|
|
#[inline]
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
fn is_empty(&self) -> bool { self.len() == 0 }
|
2015-01-01 23:53:35 -08:00
|
|
|
|
|
|
|
#[inline]
|
2015-01-27 22:52:32 -08:00
|
|
|
fn parse<T: FromStr>(&self) -> Result<T, T::Err> { FromStr::from_str(self) }
|
2014-04-30 23:06:36 -07:00
|
|
|
}
|
|
|
|
|
2015-01-21 15:55:31 -08:00
|
|
|
/// Pluck a code point out of a UTF-8-like byte slice and return the
|
|
|
|
/// index of the next code point.
|
|
|
|
#[inline]
|
2015-01-25 19:03:10 -08:00
|
|
|
#[unstable(feature = "core")]
|
2014-12-30 21:54:17 +01:00
|
|
|
pub fn char_range_at_raw(bytes: &[u8], i: uint) -> (u32, usize) {
|
2015-01-21 15:55:31 -08:00
|
|
|
if bytes[i] < 128u8 {
|
|
|
|
return (bytes[i] as u32, i + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Multibyte case is a fn to allow char_range_at to inline cleanly
|
2014-12-30 21:54:17 +01:00
|
|
|
fn multibyte_char_range_at(bytes: &[u8], i: uint) -> (u32, usize) {
|
2015-01-21 15:55:31 -08:00
|
|
|
let mut val = bytes[i] as u32;
|
2014-12-30 21:54:17 +01:00
|
|
|
let w = UTF8_CHAR_WIDTH[val as uint] as uint;
|
2015-01-21 15:55:31 -08:00
|
|
|
assert!((w != 0));
|
|
|
|
|
|
|
|
val = utf8_first_byte!(val, w);
|
|
|
|
val = utf8_acc_cont_byte!(val, bytes[i + 1]);
|
|
|
|
if w > 2 { val = utf8_acc_cont_byte!(val, bytes[i + 2]); }
|
|
|
|
if w > 3 { val = utf8_acc_cont_byte!(val, bytes[i + 3]); }
|
|
|
|
|
|
|
|
return (val, i + w);
|
|
|
|
}
|
|
|
|
|
|
|
|
multibyte_char_range_at(bytes, i)
|
|
|
|
}
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-04-30 23:06:36 -07:00
|
|
|
impl<'a> Default for &'a str {
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-04-30 23:06:36 -07:00
|
|
|
fn default() -> &'a str { "" }
|
|
|
|
}
|
librustc: Make `Copy` opt-in.
This change makes the compiler no longer infer whether types (structures
and enumerations) implement the `Copy` trait (and thus are implicitly
copyable). Rather, you must implement `Copy` yourself via `impl Copy for
MyType {}`.
A new warning has been added, `missing_copy_implementations`, to warn
you if a non-generic public type has been added that could have
implemented `Copy` but didn't.
For convenience, you may *temporarily* opt out of this behavior by using
`#![feature(opt_out_copy)]`. Note though that this feature gate will never be
accepted and will be removed by the time that 1.0 is released, so you should
transition your code away from using it.
This breaks code like:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
Change this code to:
#[deriving(Show)]
struct Point2D {
x: int,
y: int,
}
impl Copy for Point2D {}
fn main() {
let mypoint = Point2D {
x: 1,
y: 1,
};
let otherpoint = mypoint;
println!("{}{}", mypoint, otherpoint);
}
This is the backwards-incompatible part of #13231.
Part of RFC #3.
[breaking-change]
2014-12-05 17:01:33 -08:00
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a> Iterator for Lines<'a> {
|
|
|
|
type Item = &'a str;
|
|
|
|
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<&'a str> { self.inner.next() }
|
2014-12-10 19:46:38 -08:00
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
|
2015-01-08 21:36:30 -08:00
|
|
|
}
|
2015-01-04 16:16:55 -08:00
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a> DoubleEndedIterator for Lines<'a> {
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
#[inline]
|
|
|
|
fn next_back(&mut self) -> Option<&'a str> { self.inner.next_back() }
|
2015-01-08 21:36:30 -08:00
|
|
|
}
|
2015-01-04 16:16:55 -08:00
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a> Iterator for LinesAny<'a> {
|
|
|
|
type Item = &'a str;
|
|
|
|
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<&'a str> { self.inner.next() }
|
2014-12-10 19:46:38 -08:00
|
|
|
#[inline]
|
2014-12-30 21:54:17 +01:00
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
|
2015-01-08 21:36:30 -08:00
|
|
|
}
|
2015-01-04 16:16:55 -08:00
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-29 16:18:41 -05:00
|
|
|
impl<'a> DoubleEndedIterator for LinesAny<'a> {
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
#[inline]
|
|
|
|
fn next_back(&mut self) -> Option<&'a str> { self.inner.next_back() }
|
|
|
|
}
|