mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-28 03:07:24 +03:00
Auto merge of #42648 - murarth:merge-alloc-collections, r=alexcrichton
Merge crate `collections` into `alloc` This is a necessary step in order to merge #42565
This commit is contained in:
Generated
+1
-10
@@ -36,6 +36,7 @@ name = "alloc"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"core 0.0.0",
|
||||
"std_unicode 0.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -250,15 +251,6 @@ dependencies = [
|
||||
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "collections"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"alloc 0.0.0",
|
||||
"core 0.0.0",
|
||||
"std_unicode 0.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "compiler_builtins"
|
||||
version = "0.0.0"
|
||||
@@ -1594,7 +1586,6 @@ dependencies = [
|
||||
"alloc_jemalloc 0.0.0",
|
||||
"alloc_system 0.0.0",
|
||||
"build_helper 0.1.0",
|
||||
"collections 0.0.0",
|
||||
"compiler_builtins 0.0.0",
|
||||
"core 0.0.0",
|
||||
"gcc 0.3.50 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
||||
@@ -376,8 +376,8 @@ pub fn debugger_scripts(build: &Build,
|
||||
install(&build.src.join("src/etc/rust-windbg.cmd"), &sysroot.join("bin"),
|
||||
0o755);
|
||||
|
||||
cp_debugger_script("natvis/liballoc.natvis");
|
||||
cp_debugger_script("natvis/libcore.natvis");
|
||||
cp_debugger_script("natvis/libcollections.natvis");
|
||||
} else {
|
||||
cp_debugger_script("debugger_pretty_printers_common.py");
|
||||
|
||||
@@ -550,7 +550,6 @@ pub fn rust_src(build: &Build) {
|
||||
"src/liballoc_jemalloc",
|
||||
"src/liballoc_system",
|
||||
"src/libbacktrace",
|
||||
"src/libcollections",
|
||||
"src/libcompiler_builtins",
|
||||
"src/libcore",
|
||||
"src/liblibc",
|
||||
|
||||
@@ -246,7 +246,7 @@ pub fn std(build: &Build, stage: u32, target: &str) {
|
||||
// for which docs must be built.
|
||||
if !build.config.compiler_docs {
|
||||
cargo.arg("--no-deps");
|
||||
for krate in &["alloc", "collections", "core", "std", "std_unicode"] {
|
||||
for krate in &["alloc", "core", "std", "std_unicode"] {
|
||||
cargo.arg("-p").arg(krate);
|
||||
// Create all crate output directories first to make sure rustdoc uses
|
||||
// relative links.
|
||||
|
||||
@@ -110,7 +110,6 @@
|
||||
- [coerce_unsized](library-features/coerce-unsized.md)
|
||||
- [collection_placement](library-features/collection-placement.md)
|
||||
- [collections_range](library-features/collections-range.md)
|
||||
- [collections](library-features/collections.md)
|
||||
- [command_envs](library-features/command-envs.md)
|
||||
- [compiler_builtins_lib](library-features/compiler-builtins-lib.md)
|
||||
- [compiler_fences](library-features/compiler-fences.md)
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# `collections`
|
||||
|
||||
This feature is internal to the Rust compiler and is not intended for general use.
|
||||
|
||||
------------------------
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||
<Type Name="collections::vec::Vec<*>">
|
||||
<Type Name="alloc::vec::Vec<*>">
|
||||
<DisplayString>{{ size={len} }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[size]" ExcludeView="simple">len</Item>
|
||||
@@ -11,7 +11,7 @@
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="collections::vec_deque::VecDeque<*>">
|
||||
<Type Name="alloc::vec_deque::VecDeque<*>">
|
||||
<DisplayString>{{ size={tail <= head ? head - tail : buf.cap - tail + head} }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[size]" ExcludeView="simple">tail <= head ? head - tail : buf.cap - tail + head</Item>
|
||||
@@ -30,18 +30,18 @@
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="collections::linked_list::LinkedList<*>">
|
||||
<Type Name="alloc::linked_list::LinkedList<*>">
|
||||
<DisplayString>{{ size={len} }}</DisplayString>
|
||||
<Expand>
|
||||
<LinkedListItems>
|
||||
<Size>len</Size>
|
||||
<HeadPointer>*(collections::linked_list::Node<$T1> **)&head</HeadPointer>
|
||||
<NextPointer>*(collections::linked_list::Node<$T1> **)&next</NextPointer>
|
||||
<HeadPointer>*(alloc::linked_list::Node<$T1> **)&head</HeadPointer>
|
||||
<NextPointer>*(alloc::linked_list::Node<$T1> **)&next</NextPointer>
|
||||
<ValueNode>element</ValueNode>
|
||||
</LinkedListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="collections::string::String">
|
||||
<Type Name="alloc::string::String">
|
||||
<DisplayString>{*(char**)this,[vec.len]}</DisplayString>
|
||||
<StringView>*(char**)this,[vec.len]</StringView>
|
||||
<Expand>
|
||||
@@ -53,4 +53,4 @@
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
</AutoVisualizer>
|
||||
</AutoVisualizer>
|
||||
@@ -15,4 +15,4 @@ for /f "delims=" %%i in ('rustc --print=sysroot') do set rustc_sysroot=%%i
|
||||
|
||||
set rust_etc=%rustc_sysroot%\lib\rustlib\etc
|
||||
|
||||
windbg -c ".nvload %rust_etc%\libcore.natvis;.nvload %rust_etc%\libcollections.natvis;" %*
|
||||
windbg -c ".nvload %rust_etc%\liballoc.natvis; .nvload %rust_etc%\libcore.natvis;" %*
|
||||
|
||||
@@ -9,3 +9,12 @@ path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
core = { path = "../libcore" }
|
||||
std_unicode = { path = "../libstd_unicode" }
|
||||
|
||||
[[test]]
|
||||
name = "collectionstests"
|
||||
path = "../liballoc/tests/lib.rs"
|
||||
|
||||
[[bench]]
|
||||
name = "collectionsbenches"
|
||||
path = "../liballoc/benches/lib.rs"
|
||||
|
||||
+3
-2
@@ -1222,11 +1222,12 @@ mod tests {
|
||||
use std::sync::atomic;
|
||||
use std::sync::atomic::Ordering::{Acquire, SeqCst};
|
||||
use std::thread;
|
||||
use std::vec::Vec;
|
||||
use super::{Arc, Weak};
|
||||
use std::sync::Mutex;
|
||||
use std::convert::From;
|
||||
|
||||
use super::{Arc, Weak};
|
||||
use vec::Vec;
|
||||
|
||||
struct Canary(*mut atomic::AtomicUsize);
|
||||
|
||||
impl Drop for Canary {
|
||||
|
||||
@@ -95,6 +95,7 @@
|
||||
#[unstable(feature = "box_heap",
|
||||
reason = "may be renamed; uncertain about custom allocator design",
|
||||
issue = "27779")]
|
||||
#[allow(missing_debug_implementations)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct ExchangeHeapSingleton {
|
||||
_force_singleton: (),
|
||||
@@ -129,6 +130,7 @@ pub struct ExchangeHeapSingleton {
|
||||
#[unstable(feature = "placement_in",
|
||||
reason = "placement box design is still being worked out.",
|
||||
issue = "27779")]
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct IntermediateBox<T: ?Sized> {
|
||||
ptr: *mut u8,
|
||||
size: usize,
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
// - A node of length `n` has `n` keys, `n` values, and (in an internal node) `n + 1` edges.
|
||||
// This implies that even an empty internal node has at least one edge.
|
||||
|
||||
use alloc::heap;
|
||||
use core::marker::PhantomData;
|
||||
use core::mem;
|
||||
use core::nonzero::NonZero;
|
||||
@@ -49,6 +48,7 @@
|
||||
use core::slice;
|
||||
|
||||
use boxed::Box;
|
||||
use heap;
|
||||
|
||||
const B: usize = 6;
|
||||
pub const MIN_LEN: usize = B - 1;
|
||||
+150
-10
@@ -1,4 +1,4 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2014-2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
@@ -8,18 +8,16 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! # The Rust core allocation library
|
||||
//! # The Rust core allocation and collections library
|
||||
//!
|
||||
//! This is the lowest level library through which allocation in Rust can be
|
||||
//! performed.
|
||||
//! This library provides smart pointers and collections for managing
|
||||
//! heap-allocated values.
|
||||
//!
|
||||
//! This library, like libcore, is not intended for general usage, but rather as
|
||||
//! a building block of other libraries. The types and interfaces in this
|
||||
//! library are reexported through the [standard library](../std/index.html),
|
||||
//! and should not be used through this library.
|
||||
//!
|
||||
//! Currently, there are four major definitions in this library.
|
||||
//!
|
||||
//! ## Boxed values
|
||||
//!
|
||||
//! The [`Box`](boxed/index.html) type is a smart pointer type. There can
|
||||
@@ -51,6 +49,12 @@
|
||||
//! paired with synchronization primitives such as mutexes to allow mutation of
|
||||
//! shared resources.
|
||||
//!
|
||||
//! ## Collections
|
||||
//!
|
||||
//! Implementations of the most common general purpose data structures are
|
||||
//! defined in this library. They are reexported through the
|
||||
//! [standard collections library](../std/collections/index.html).
|
||||
//!
|
||||
//! ## Heap interfaces
|
||||
//!
|
||||
//! The [`heap`](heap/index.html) module defines the low-level interface to the
|
||||
@@ -71,8 +75,20 @@
|
||||
#![no_std]
|
||||
#![needs_allocator]
|
||||
#![deny(warnings)]
|
||||
#![deny(missing_debug_implementations)]
|
||||
|
||||
#![cfg_attr(test, allow(deprecated))] // rand
|
||||
#![cfg_attr(test, feature(placement_in))]
|
||||
#![cfg_attr(not(test), feature(char_escape_debug))]
|
||||
#![cfg_attr(not(test), feature(core_float))]
|
||||
#![cfg_attr(not(test), feature(exact_size_is_empty))]
|
||||
#![cfg_attr(not(test), feature(slice_rotate))]
|
||||
#![cfg_attr(not(test), feature(sort_unstable))]
|
||||
#![cfg_attr(not(test), feature(str_checked_slicing))]
|
||||
#![cfg_attr(test, feature(rand, test))]
|
||||
#![feature(allocator)]
|
||||
#![feature(allow_internal_unstable)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(cfg_target_has_atomic)]
|
||||
#![feature(coerce_unsized)]
|
||||
@@ -80,16 +96,33 @@
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(custom_attribute)]
|
||||
#![feature(dropck_eyepatch)]
|
||||
#![cfg_attr(not(test), feature(exact_size_is_empty))]
|
||||
#![feature(exact_size_is_empty)]
|
||||
#![feature(fmt_internals)]
|
||||
#![feature(fundamental)]
|
||||
#![feature(fused)]
|
||||
#![feature(generic_param_attrs)]
|
||||
#![feature(i128_type)]
|
||||
#![feature(inclusive_range)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(manually_drop)]
|
||||
#![feature(needs_allocator)]
|
||||
#![feature(nonzero)]
|
||||
#![feature(offset_to)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(pattern)]
|
||||
#![feature(placement_in_syntax)]
|
||||
#![feature(placement_new_protocol)]
|
||||
#![feature(shared)]
|
||||
#![feature(slice_get_slice)]
|
||||
#![feature(slice_patterns)]
|
||||
#![feature(slice_rsplit)]
|
||||
#![feature(specialization)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(str_internals)]
|
||||
#![feature(str_mut_extras)]
|
||||
#![feature(trusted_len)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(unicode)]
|
||||
#![feature(unique)]
|
||||
#![feature(unsize)]
|
||||
|
||||
@@ -101,6 +134,10 @@
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
extern crate std;
|
||||
#[cfg(test)]
|
||||
extern crate test;
|
||||
|
||||
extern crate std_unicode;
|
||||
|
||||
// Module with internal macros used by other modules (needs to be included before other modules).
|
||||
#[macro_use]
|
||||
@@ -120,7 +157,7 @@
|
||||
pub mod boxed;
|
||||
#[cfg(test)]
|
||||
mod boxed {
|
||||
pub use std::boxed::{Box, HEAP};
|
||||
pub use std::boxed::{Box, IntermediateBox, HEAP};
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod boxed_test;
|
||||
@@ -128,8 +165,111 @@ mod boxed {
|
||||
pub mod arc;
|
||||
pub mod rc;
|
||||
pub mod raw_vec;
|
||||
#[unstable(feature = "str_box_extras", issue = "41119")]
|
||||
pub mod str;
|
||||
pub mod oom;
|
||||
|
||||
// collections modules
|
||||
pub mod binary_heap;
|
||||
mod btree;
|
||||
pub mod borrow;
|
||||
pub mod fmt;
|
||||
pub mod linked_list;
|
||||
pub mod range;
|
||||
pub mod slice;
|
||||
pub mod str;
|
||||
pub mod string;
|
||||
pub mod vec;
|
||||
pub mod vec_deque;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub mod btree_map {
|
||||
//! A map based on a B-Tree.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use btree::map::*;
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub mod btree_set {
|
||||
//! A set based on a B-Tree.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use btree::set::*;
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
mod std {
|
||||
pub use core::ops; // RangeFull
|
||||
}
|
||||
|
||||
/// An endpoint of a range of keys.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// `Bound`s are range endpoints:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(collections_range)]
|
||||
///
|
||||
/// use std::collections::range::RangeArgument;
|
||||
/// use std::collections::Bound::*;
|
||||
///
|
||||
/// assert_eq!((..100).start(), Unbounded);
|
||||
/// assert_eq!((1..12).start(), Included(&1));
|
||||
/// assert_eq!((1..12).end(), Excluded(&12));
|
||||
/// ```
|
||||
///
|
||||
/// Using a tuple of `Bound`s as an argument to [`BTreeMap::range`].
|
||||
/// Note that in most cases, it's better to use range syntax (`1..5`) instead.
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::BTreeMap;
|
||||
/// use std::collections::Bound::{Excluded, Included, Unbounded};
|
||||
///
|
||||
/// let mut map = BTreeMap::new();
|
||||
/// map.insert(3, "a");
|
||||
/// map.insert(5, "b");
|
||||
/// map.insert(8, "c");
|
||||
///
|
||||
/// for (key, value) in map.range((Excluded(3), Included(8))) {
|
||||
/// println!("{}: {}", key, value);
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(Some((&3, &"a")), map.range((Unbounded, Included(5))).next());
|
||||
/// ```
|
||||
///
|
||||
/// [`BTreeMap::range`]: btree_map/struct.BTreeMap.html#method.range
|
||||
#[stable(feature = "collections_bound", since = "1.17.0")]
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
|
||||
pub enum Bound<T> {
|
||||
/// An inclusive bound.
|
||||
#[stable(feature = "collections_bound", since = "1.17.0")]
|
||||
Included(T),
|
||||
/// An exclusive bound.
|
||||
#[stable(feature = "collections_bound", since = "1.17.0")]
|
||||
Excluded(T),
|
||||
/// An infinite endpoint. Indicates that there is no bound in this direction.
|
||||
#[stable(feature = "collections_bound", since = "1.17.0")]
|
||||
Unbounded,
|
||||
}
|
||||
|
||||
/// An intermediate trait for specialization of `Extend`.
|
||||
#[doc(hidden)]
|
||||
trait SpecExtend<I: IntoIterator> {
|
||||
/// Extends `self` with the contents of the given iterator.
|
||||
fn spec_extend(&mut self, iter: I);
|
||||
}
|
||||
|
||||
pub use oom::oom;
|
||||
|
||||
#[doc(no_inline)]
|
||||
pub use binary_heap::BinaryHeap;
|
||||
#[doc(no_inline)]
|
||||
pub use btree_map::BTreeMap;
|
||||
#[doc(no_inline)]
|
||||
pub use btree_set::BTreeSet;
|
||||
#[doc(no_inline)]
|
||||
pub use linked_list::LinkedList;
|
||||
#[doc(no_inline)]
|
||||
pub use vec_deque::VecDeque;
|
||||
#[doc(no_inline)]
|
||||
pub use string::String;
|
||||
#[doc(no_inline)]
|
||||
pub use vec::Vec;
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use alloc::boxed::{Box, IntermediateBox};
|
||||
use core::cmp::Ordering;
|
||||
use core::fmt;
|
||||
use core::hash::{Hasher, Hash};
|
||||
@@ -32,6 +31,7 @@
|
||||
use core::ops::{BoxPlace, InPlace, Place, Placer};
|
||||
use core::ptr::{self, Shared};
|
||||
|
||||
use boxed::{Box, IntermediateBox};
|
||||
use super::SpecExtend;
|
||||
|
||||
/// A doubly-linked list with owned nodes.
|
||||
@@ -8,6 +8,89 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/// Creates a `Vec` containing the arguments.
|
||||
///
|
||||
/// `vec!` allows `Vec`s to be defined with the same syntax as array expressions.
|
||||
/// There are two forms of this macro:
|
||||
///
|
||||
/// - Create a `Vec` containing a given list of elements:
|
||||
///
|
||||
/// ```
|
||||
/// let v = vec![1, 2, 3];
|
||||
/// assert_eq!(v[0], 1);
|
||||
/// assert_eq!(v[1], 2);
|
||||
/// assert_eq!(v[2], 3);
|
||||
/// ```
|
||||
///
|
||||
/// - Create a `Vec` from a given element and size:
|
||||
///
|
||||
/// ```
|
||||
/// let v = vec![1; 3];
|
||||
/// assert_eq!(v, [1, 1, 1]);
|
||||
/// ```
|
||||
///
|
||||
/// Note that unlike array expressions this syntax supports all elements
|
||||
/// which implement `Clone` and the number of elements doesn't have to be
|
||||
/// a constant.
|
||||
///
|
||||
/// This will use `clone()` to duplicate an expression, so one should be careful
|
||||
/// using this with types having a nonstandard `Clone` implementation. For
|
||||
/// example, `vec![Rc::new(1); 5]` will create a vector of five references
|
||||
/// to the same boxed integer value, not five references pointing to independently
|
||||
/// boxed integers.
|
||||
#[cfg(not(test))]
|
||||
#[macro_export]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable]
|
||||
macro_rules! vec {
|
||||
($elem:expr; $n:expr) => (
|
||||
$crate::vec::from_elem($elem, $n)
|
||||
);
|
||||
($($x:expr),*) => (
|
||||
<[_]>::into_vec(box [$($x),*])
|
||||
);
|
||||
($($x:expr,)*) => (vec![$($x),*])
|
||||
}
|
||||
|
||||
// HACK(japaric): with cfg(test) the inherent `[T]::into_vec` method, which is
|
||||
// required for this macro definition, is not available. Instead use the
|
||||
// `slice::into_vec` function which is only available with cfg(test)
|
||||
// NB see the slice::hack module in slice.rs for more information
|
||||
#[cfg(test)]
|
||||
macro_rules! vec {
|
||||
($elem:expr; $n:expr) => (
|
||||
$crate::vec::from_elem($elem, $n)
|
||||
);
|
||||
($($x:expr),*) => (
|
||||
$crate::slice::into_vec(box [$($x),*])
|
||||
);
|
||||
($($x:expr,)*) => (vec![$($x),*])
|
||||
}
|
||||
|
||||
/// Use the syntax described in `std::fmt` to create a value of type `String`.
|
||||
/// See [`std::fmt`][fmt] for more information.
|
||||
///
|
||||
/// [fmt]: ../std/fmt/index.html
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// `format!` panics if a formatting trait implementation returns an error.
|
||||
/// This indicates an incorrect implementation
|
||||
/// since `fmt::Write for String` never returns an error itself.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// format!("test");
|
||||
/// format!("hello {}", "world!");
|
||||
/// format!("x = {}, y = {y}", 10, y = 30);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
macro_rules! format {
|
||||
($($arg:tt)*) => ($crate::fmt::format(format_args!($($arg)*)))
|
||||
}
|
||||
|
||||
// Private macro to get the offset of a struct field in bytes from the address of the struct.
|
||||
macro_rules! offset_of {
|
||||
($container:path, $field:ident) => {{
|
||||
|
||||
@@ -27,14 +27,14 @@ pub trait RangeArgument<T: ?Sized> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(collections)]
|
||||
/// #![feature(alloc)]
|
||||
/// #![feature(collections_range)]
|
||||
///
|
||||
/// extern crate collections;
|
||||
/// extern crate alloc;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// use collections::range::RangeArgument;
|
||||
/// use collections::Bound::*;
|
||||
/// use alloc::range::RangeArgument;
|
||||
/// use alloc::Bound::*;
|
||||
///
|
||||
/// assert_eq!((..10).start(), Unbounded);
|
||||
/// assert_eq!((3..10).start(), Included(&3));
|
||||
@@ -49,14 +49,14 @@ pub trait RangeArgument<T: ?Sized> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(collections)]
|
||||
/// #![feature(alloc)]
|
||||
/// #![feature(collections_range)]
|
||||
///
|
||||
/// extern crate collections;
|
||||
/// extern crate alloc;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// use collections::range::RangeArgument;
|
||||
/// use collections::Bound::*;
|
||||
/// use alloc::range::RangeArgument;
|
||||
/// use alloc::Bound::*;
|
||||
///
|
||||
/// assert_eq!((3..).end(), Unbounded);
|
||||
/// assert_eq!((3..10).end(), Excluded(&10));
|
||||
@@ -44,6 +44,7 @@
|
||||
/// `shrink_to_fit`, and `from_box` will actually set RawVec's private capacity
|
||||
/// field. This allows zero-sized types to not be special-cased by consumers of
|
||||
/// this type.
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct RawVec<T> {
|
||||
ptr: Unique<T>,
|
||||
cap: usize,
|
||||
|
||||
@@ -97,7 +97,6 @@
|
||||
// It's cleaner to just turn off the unused_imports warning than to fix them.
|
||||
#![cfg_attr(test, allow(unused_imports, dead_code))]
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use core::cmp::Ordering::{self, Less};
|
||||
use core::mem::size_of;
|
||||
use core::mem;
|
||||
@@ -105,6 +104,7 @@
|
||||
use core::slice as core_slice;
|
||||
|
||||
use borrow::{Borrow, BorrowMut, ToOwned};
|
||||
use boxed::Box;
|
||||
use vec::Vec;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@@ -141,7 +141,7 @@
|
||||
// `core::slice::SliceExt` - we need to supply these functions for the
|
||||
// `test_permutations` test
|
||||
mod hack {
|
||||
use alloc::boxed::Box;
|
||||
use boxed::Box;
|
||||
use core::mem;
|
||||
|
||||
#[cfg(test)]
|
||||
+1983
-2
@@ -8,11 +8,1992 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Methods for dealing with boxed strings.
|
||||
use core::mem;
|
||||
//! Unicode string slices.
|
||||
//!
|
||||
//! The `&str` type is one of the two main string types, the other being `String`.
|
||||
//! Unlike its `String` counterpart, its contents are borrowed.
|
||||
//!
|
||||
//! # Basic Usage
|
||||
//!
|
||||
//! A basic string declaration of `&str` type:
|
||||
//!
|
||||
//! ```
|
||||
//! let hello_world = "Hello, World!";
|
||||
//! ```
|
||||
//!
|
||||
//! Here we have declared a string literal, also known as a string slice.
|
||||
//! String literals have a static lifetime, which means the string `hello_world`
|
||||
//! is guaranteed to be valid for the duration of the entire program.
|
||||
//! We can explicitly specify `hello_world`'s lifetime as well:
|
||||
//!
|
||||
//! ```
|
||||
//! let hello_world: &'static str = "Hello, world!";
|
||||
//! ```
|
||||
//!
|
||||
//! *[See also the `str` primitive type](../../std/primitive.str.html).*
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
// Many of the usings in this module are only used in the test configuration.
|
||||
// It's cleaner to just turn off the unused_imports warning than to fix them.
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use core::fmt;
|
||||
use core::str as core_str;
|
||||
use core::str::pattern::Pattern;
|
||||
use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
|
||||
use core::mem;
|
||||
use core::iter::FusedIterator;
|
||||
use std_unicode::str::{UnicodeStr, Utf16Encoder};
|
||||
|
||||
use vec_deque::VecDeque;
|
||||
use borrow::{Borrow, ToOwned};
|
||||
use string::String;
|
||||
use std_unicode;
|
||||
use vec::Vec;
|
||||
use slice::{SliceConcatExt, SliceIndex};
|
||||
use boxed::Box;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{FromStr, Utf8Error};
|
||||
#[allow(deprecated)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{Lines, LinesAny};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{Split, RSplit};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{SplitN, RSplitN};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{SplitTerminator, RSplitTerminator};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{Matches, RMatches};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{MatchIndices, RMatchIndices};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{from_utf8, from_utf8_mut, Chars, CharIndices, Bytes};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{from_utf8_unchecked, from_utf8_unchecked_mut, ParseBoolError};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use std_unicode::str::SplitWhitespace;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::pattern;
|
||||
|
||||
|
||||
#[unstable(feature = "slice_concat_ext",
|
||||
reason = "trait should not have to exist",
|
||||
issue = "27747")]
|
||||
impl<S: Borrow<str>> SliceConcatExt<str> for [S] {
|
||||
type Output = String;
|
||||
|
||||
fn concat(&self) -> String {
|
||||
if self.is_empty() {
|
||||
return String::new();
|
||||
}
|
||||
|
||||
// `len` calculation may overflow but push_str will check boundaries
|
||||
let len = self.iter().map(|s| s.borrow().len()).sum();
|
||||
let mut result = String::with_capacity(len);
|
||||
|
||||
for s in self {
|
||||
result.push_str(s.borrow())
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn join(&self, sep: &str) -> String {
|
||||
if self.is_empty() {
|
||||
return String::new();
|
||||
}
|
||||
|
||||
// concat is faster
|
||||
if sep.is_empty() {
|
||||
return self.concat();
|
||||
}
|
||||
|
||||
// this is wrong without the guarantee that `self` is non-empty
|
||||
// `len` calculation may overflow but push_str but will check boundaries
|
||||
let len = sep.len() * (self.len() - 1) +
|
||||
self.iter().map(|s| s.borrow().len()).sum::<usize>();
|
||||
let mut result = String::with_capacity(len);
|
||||
let mut first = true;
|
||||
|
||||
for s in self {
|
||||
if first {
|
||||
first = false;
|
||||
} else {
|
||||
result.push_str(sep);
|
||||
}
|
||||
result.push_str(s.borrow());
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn connect(&self, sep: &str) -> String {
|
||||
self.join(sep)
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator of [`u16`] over the string encoded as UTF-16.
|
||||
///
|
||||
/// [`u16`]: ../../std/primitive.u16.html
|
||||
///
|
||||
/// This struct is created by the [`encode_utf16`] method on [`str`].
|
||||
/// See its documentation for more.
|
||||
///
|
||||
/// [`encode_utf16`]: ../../std/primitive.str.html#method.encode_utf16
|
||||
/// [`str`]: ../../std/primitive.str.html
|
||||
#[derive(Clone)]
|
||||
#[stable(feature = "encode_utf16", since = "1.8.0")]
|
||||
pub struct EncodeUtf16<'a> {
|
||||
encoder: Utf16Encoder<Chars<'a>>,
|
||||
}
|
||||
|
||||
#[stable(feature = "collection_debug", since = "1.17.0")]
|
||||
impl<'a> fmt::Debug for EncodeUtf16<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.pad("EncodeUtf16 { .. }")
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "encode_utf16", since = "1.8.0")]
|
||||
impl<'a> Iterator for EncodeUtf16<'a> {
|
||||
type Item = u16;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<u16> {
|
||||
self.encoder.next()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.encoder.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "fused", issue = "35602")]
|
||||
impl<'a> FusedIterator for EncodeUtf16<'a> {}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Borrow<str> for String {
|
||||
#[inline]
|
||||
fn borrow(&self) -> &str {
|
||||
&self[..]
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl ToOwned for str {
|
||||
type Owned = String;
|
||||
fn to_owned(&self) -> String {
|
||||
unsafe { String::from_utf8_unchecked(self.as_bytes().to_owned()) }
|
||||
}
|
||||
|
||||
fn clone_into(&self, target: &mut String) {
|
||||
let mut b = mem::replace(target, String::new()).into_bytes();
|
||||
self.as_bytes().clone_into(&mut b);
|
||||
*target = unsafe { String::from_utf8_unchecked(b) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Methods for string slices.
|
||||
#[lang = "str"]
|
||||
#[cfg(not(test))]
|
||||
impl str {
|
||||
/// Returns the length of `self`.
|
||||
///
|
||||
/// This length is in bytes, not [`char`]s or graphemes. In other words,
|
||||
/// it may not be what a human considers the length of the string.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let len = "foo".len();
|
||||
/// assert_eq!(3, len);
|
||||
///
|
||||
/// let len = "ƒoo".len(); // fancy f!
|
||||
/// assert_eq!(4, len);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
core_str::StrExt::len(self)
|
||||
}
|
||||
|
||||
/// Returns `true` if `self` has a length of zero bytes.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "";
|
||||
/// assert!(s.is_empty());
|
||||
///
|
||||
/// let s = "not empty";
|
||||
/// assert!(!s.is_empty());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
core_str::StrExt::is_empty(self)
|
||||
}
|
||||
|
||||
/// Checks that `index`-th byte lies at the start and/or end of a
|
||||
/// UTF-8 code point sequence.
|
||||
///
|
||||
/// The start and end of the string (when `index == self.len()`) are
|
||||
/// considered to be
|
||||
/// boundaries.
|
||||
///
|
||||
/// Returns `false` if `index` is greater than `self.len()`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
/// assert!(s.is_char_boundary(0));
|
||||
/// // start of `老`
|
||||
/// assert!(s.is_char_boundary(6));
|
||||
/// assert!(s.is_char_boundary(s.len()));
|
||||
///
|
||||
/// // second byte of `ö`
|
||||
/// assert!(!s.is_char_boundary(2));
|
||||
///
|
||||
/// // third byte of `老`
|
||||
/// assert!(!s.is_char_boundary(8));
|
||||
/// ```
|
||||
#[stable(feature = "is_char_boundary", since = "1.9.0")]
|
||||
#[inline]
|
||||
pub fn is_char_boundary(&self, index: usize) -> bool {
|
||||
core_str::StrExt::is_char_boundary(self, index)
|
||||
}
|
||||
|
||||
/// Converts a string slice to a byte slice.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let bytes = "bors".as_bytes();
|
||||
/// assert_eq!(b"bors", bytes);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline(always)]
|
||||
pub fn as_bytes(&self) -> &[u8] {
|
||||
core_str::StrExt::as_bytes(self)
|
||||
}
|
||||
|
||||
/// Converts a mutable string slice to a mutable byte slice.
|
||||
#[unstable(feature = "str_mut_extras", issue = "41119")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
|
||||
core_str::StrExt::as_bytes_mut(self)
|
||||
}
|
||||
|
||||
/// Converts a string slice to a raw pointer.
|
||||
///
|
||||
/// As string slices are a slice of bytes, the raw pointer points to a
|
||||
/// [`u8`]. This pointer will be pointing to the first byte of the string
|
||||
/// slice.
|
||||
///
|
||||
/// [`u8`]: primitive.u8.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Hello";
|
||||
/// let ptr = s.as_ptr();
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn as_ptr(&self) -> *const u8 {
|
||||
core_str::StrExt::as_ptr(self)
|
||||
}
|
||||
|
||||
/// Returns a subslice of `str`.
|
||||
///
|
||||
/// This is the non-panicking alternative to indexing the `str`. Returns
|
||||
/// [`None`] whenever equivalent indexing operation would panic.
|
||||
///
|
||||
/// [`None`]: option/enum.Option.html#variant.None
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(str_checked_slicing)]
|
||||
/// let v = "🗻∈🌏";
|
||||
/// assert_eq!(Some("🗻"), v.get(0..4));
|
||||
/// assert!(v.get(1..).is_none());
|
||||
/// assert!(v.get(..8).is_none());
|
||||
/// assert!(v.get(..42).is_none());
|
||||
/// ```
|
||||
#[unstable(feature = "str_checked_slicing", issue = "39932")]
|
||||
#[inline]
|
||||
pub fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
|
||||
core_str::StrExt::get(self, i)
|
||||
}
|
||||
|
||||
/// Returns a mutable subslice of `str`.
|
||||
///
|
||||
/// This is the non-panicking alternative to indexing the `str`. Returns
|
||||
/// [`None`] whenever equivalent indexing operation would panic.
|
||||
///
|
||||
/// [`None`]: option/enum.Option.html#variant.None
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(str_checked_slicing)]
|
||||
/// let mut v = String::from("🗻∈🌏");
|
||||
/// assert_eq!(Some("🗻"), v.get_mut(0..4).map(|v| &*v));
|
||||
/// assert!(v.get_mut(1..).is_none());
|
||||
/// assert!(v.get_mut(..8).is_none());
|
||||
/// assert!(v.get_mut(..42).is_none());
|
||||
/// ```
|
||||
#[unstable(feature = "str_checked_slicing", issue = "39932")]
|
||||
#[inline]
|
||||
pub fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
|
||||
core_str::StrExt::get_mut(self, i)
|
||||
}
|
||||
|
||||
/// Returns a unchecked subslice of `str`.
|
||||
///
|
||||
/// This is the unchecked alternative to indexing the `str`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Callers of this function are responsible that these preconditions are
|
||||
/// satisfied:
|
||||
///
|
||||
/// * The starting index must come before the ending index;
|
||||
/// * Indexes must be within bounds of the original slice;
|
||||
/// * Indexes must lie on UTF-8 sequence boundaries.
|
||||
///
|
||||
/// Failing that, the returned string slice may reference invalid memory or
|
||||
/// violate the invariants communicated by the `str` type.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(str_checked_slicing)]
|
||||
/// let v = "🗻∈🌏";
|
||||
/// unsafe {
|
||||
/// assert_eq!("🗻", v.get_unchecked(0..4));
|
||||
/// assert_eq!("∈", v.get_unchecked(4..7));
|
||||
/// assert_eq!("🌏", v.get_unchecked(7..11));
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "str_checked_slicing", issue = "39932")]
|
||||
#[inline]
|
||||
pub unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output {
|
||||
core_str::StrExt::get_unchecked(self, i)
|
||||
}
|
||||
|
||||
/// Returns a mutable, unchecked subslice of `str`.
|
||||
///
|
||||
/// This is the unchecked alternative to indexing the `str`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Callers of this function are responsible that these preconditions are
|
||||
/// satisfied:
|
||||
///
|
||||
/// * The starting index must come before the ending index;
|
||||
/// * Indexes must be within bounds of the original slice;
|
||||
/// * Indexes must lie on UTF-8 sequence boundaries.
|
||||
///
|
||||
/// Failing that, the returned string slice may reference invalid memory or
|
||||
/// violate the invariants communicated by the `str` type.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(str_checked_slicing)]
|
||||
/// let mut v = String::from("🗻∈🌏");
|
||||
/// unsafe {
|
||||
/// assert_eq!("🗻", v.get_unchecked_mut(0..4));
|
||||
/// assert_eq!("∈", v.get_unchecked_mut(4..7));
|
||||
/// assert_eq!("🌏", v.get_unchecked_mut(7..11));
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "str_checked_slicing", issue = "39932")]
|
||||
#[inline]
|
||||
pub unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output {
|
||||
core_str::StrExt::get_unchecked_mut(self, i)
|
||||
}
|
||||
|
||||
/// Creates a string slice from another string slice, bypassing safety
|
||||
/// checks.
|
||||
///
|
||||
/// This is generally not recommended, use with caution! For a safe
|
||||
/// alternative see [`str`] and [`Index`].
|
||||
///
|
||||
/// [`str`]: primitive.str.html
|
||||
/// [`Index`]: ops/trait.Index.html
|
||||
///
|
||||
/// This new slice goes from `begin` to `end`, including `begin` but
|
||||
/// excluding `end`.
|
||||
///
|
||||
/// To get a mutable string slice instead, see the
|
||||
/// [`slice_mut_unchecked`] method.
|
||||
///
|
||||
/// [`slice_mut_unchecked`]: #method.slice_mut_unchecked
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Callers of this function are responsible that three preconditions are
|
||||
/// satisfied:
|
||||
///
|
||||
/// * `begin` must come before `end`.
|
||||
/// * `begin` and `end` must be byte positions within the string slice.
|
||||
/// * `begin` and `end` must lie on UTF-8 sequence boundaries.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
///
|
||||
/// unsafe {
|
||||
/// assert_eq!("Löwe 老虎 Léopard", s.slice_unchecked(0, 21));
|
||||
/// }
|
||||
///
|
||||
/// let s = "Hello, world!";
|
||||
///
|
||||
/// unsafe {
|
||||
/// assert_eq!("world", s.slice_unchecked(7, 12));
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
|
||||
core_str::StrExt::slice_unchecked(self, begin, end)
|
||||
}
|
||||
|
||||
/// Creates a string slice from another string slice, bypassing safety
|
||||
/// checks.
|
||||
/// This is generally not recommended, use with caution! For a safe
|
||||
/// alternative see [`str`] and [`IndexMut`].
|
||||
///
|
||||
/// [`str`]: primitive.str.html
|
||||
/// [`IndexMut`]: ops/trait.IndexMut.html
|
||||
///
|
||||
/// This new slice goes from `begin` to `end`, including `begin` but
|
||||
/// excluding `end`.
|
||||
///
|
||||
/// To get an immutable string slice instead, see the
|
||||
/// [`slice_unchecked`] method.
|
||||
///
|
||||
/// [`slice_unchecked`]: #method.slice_unchecked
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Callers of this function are responsible that three preconditions are
|
||||
/// satisfied:
|
||||
///
|
||||
/// * `begin` must come before `end`.
|
||||
/// * `begin` and `end` must be byte positions within the string slice.
|
||||
/// * `begin` and `end` must lie on UTF-8 sequence boundaries.
|
||||
#[stable(feature = "str_slice_mut", since = "1.5.0")]
|
||||
#[inline]
|
||||
pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str {
|
||||
core_str::StrExt::slice_mut_unchecked(self, begin, end)
|
||||
}
|
||||
|
||||
/// Divide one string slice into two at an index.
|
||||
///
|
||||
/// The argument, `mid`, should be a byte offset from the start of the
|
||||
/// string. It must also be on the boundary of a UTF-8 code point.
|
||||
///
|
||||
/// The two slices returned go from the start of the string slice to `mid`,
|
||||
/// and from `mid` to the end of the string slice.
|
||||
///
|
||||
/// To get mutable string slices instead, see the [`split_at_mut`]
|
||||
/// method.
|
||||
///
|
||||
/// [`split_at_mut`]: #method.split_at_mut
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `mid` is not on a UTF-8 code point boundary, or if it is
|
||||
/// beyond the last code point of the string slice.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Per Martin-Löf";
|
||||
///
|
||||
/// let (first, last) = s.split_at(3);
|
||||
///
|
||||
/// assert_eq!("Per", first);
|
||||
/// assert_eq!(" Martin-Löf", last);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "str_split_at", since = "1.4.0")]
|
||||
pub fn split_at(&self, mid: usize) -> (&str, &str) {
|
||||
core_str::StrExt::split_at(self, mid)
|
||||
}
|
||||
|
||||
/// Divide one mutable string slice into two at an index.
|
||||
///
|
||||
/// The argument, `mid`, should be a byte offset from the start of the
|
||||
/// string. It must also be on the boundary of a UTF-8 code point.
|
||||
///
|
||||
/// The two slices returned go from the start of the string slice to `mid`,
|
||||
/// and from `mid` to the end of the string slice.
|
||||
///
|
||||
/// To get immutable string slices instead, see the [`split_at`] method.
|
||||
///
|
||||
/// [`split_at`]: #method.split_at
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `mid` is not on a UTF-8 code point boundary, or if it is
|
||||
/// beyond the last code point of the string slice.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let mut s = "Per Martin-Löf".to_string();
|
||||
///
|
||||
/// let (first, last) = s.split_at_mut(3);
|
||||
///
|
||||
/// assert_eq!("Per", first);
|
||||
/// assert_eq!(" Martin-Löf", last);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "str_split_at", since = "1.4.0")]
|
||||
pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
|
||||
core_str::StrExt::split_at_mut(self, mid)
|
||||
}
|
||||
|
||||
/// Returns an iterator over the [`char`]s of a string slice.
|
||||
///
|
||||
/// As a string slice consists of valid UTF-8, we can iterate through a
|
||||
/// string slice by [`char`]. This method returns such an iterator.
|
||||
///
|
||||
/// It's important to remember that [`char`] represents a Unicode Scalar
|
||||
/// Value, and may not match your idea of what a 'character' is. Iteration
|
||||
/// over grapheme clusters may be what you actually want.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let word = "goodbye";
|
||||
///
|
||||
/// let count = word.chars().count();
|
||||
/// assert_eq!(7, count);
|
||||
///
|
||||
/// let mut chars = word.chars();
|
||||
///
|
||||
/// assert_eq!(Some('g'), chars.next());
|
||||
/// assert_eq!(Some('o'), chars.next());
|
||||
/// assert_eq!(Some('o'), chars.next());
|
||||
/// assert_eq!(Some('d'), chars.next());
|
||||
/// assert_eq!(Some('b'), chars.next());
|
||||
/// assert_eq!(Some('y'), chars.next());
|
||||
/// assert_eq!(Some('e'), chars.next());
|
||||
///
|
||||
/// assert_eq!(None, chars.next());
|
||||
/// ```
|
||||
///
|
||||
/// Remember, [`char`]s may not match your human intuition about characters:
|
||||
///
|
||||
/// ```
|
||||
/// let y = "y̆";
|
||||
///
|
||||
/// let mut chars = y.chars();
|
||||
///
|
||||
/// assert_eq!(Some('y'), chars.next()); // not 'y̆'
|
||||
/// assert_eq!(Some('\u{0306}'), chars.next());
|
||||
///
|
||||
/// assert_eq!(None, chars.next());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn chars(&self) -> Chars {
|
||||
core_str::StrExt::chars(self)
|
||||
}
|
||||
/// Returns an iterator over the [`char`]s of a string slice, and their
|
||||
/// positions.
|
||||
///
|
||||
/// As a string slice consists of valid UTF-8, we can iterate through a
|
||||
/// string slice by [`char`]. This method returns an iterator of both
|
||||
/// these [`char`]s, as well as their byte positions.
|
||||
///
|
||||
/// The iterator yields tuples. The position is first, the [`char`] is
|
||||
/// second.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let word = "goodbye";
|
||||
///
|
||||
/// let count = word.char_indices().count();
|
||||
/// assert_eq!(7, count);
|
||||
///
|
||||
/// let mut char_indices = word.char_indices();
|
||||
///
|
||||
/// assert_eq!(Some((0, 'g')), char_indices.next());
|
||||
/// assert_eq!(Some((1, 'o')), char_indices.next());
|
||||
/// assert_eq!(Some((2, 'o')), char_indices.next());
|
||||
/// assert_eq!(Some((3, 'd')), char_indices.next());
|
||||
/// assert_eq!(Some((4, 'b')), char_indices.next());
|
||||
/// assert_eq!(Some((5, 'y')), char_indices.next());
|
||||
/// assert_eq!(Some((6, 'e')), char_indices.next());
|
||||
///
|
||||
/// assert_eq!(None, char_indices.next());
|
||||
/// ```
|
||||
///
|
||||
/// Remember, [`char`]s may not match your human intuition about characters:
|
||||
///
|
||||
/// ```
|
||||
/// let y = "y̆";
|
||||
///
|
||||
/// let mut char_indices = y.char_indices();
|
||||
///
|
||||
/// assert_eq!(Some((0, 'y')), char_indices.next()); // not (0, 'y̆')
|
||||
/// assert_eq!(Some((1, '\u{0306}')), char_indices.next());
|
||||
///
|
||||
/// assert_eq!(None, char_indices.next());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn char_indices(&self) -> CharIndices {
|
||||
core_str::StrExt::char_indices(self)
|
||||
}
|
||||
|
||||
/// An iterator over the bytes of a string slice.
|
||||
///
|
||||
/// As a string slice consists of a sequence of bytes, we can iterate
|
||||
/// through a string slice by byte. This method returns such an iterator.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let mut bytes = "bors".bytes();
|
||||
///
|
||||
/// assert_eq!(Some(b'b'), bytes.next());
|
||||
/// assert_eq!(Some(b'o'), bytes.next());
|
||||
/// assert_eq!(Some(b'r'), bytes.next());
|
||||
/// assert_eq!(Some(b's'), bytes.next());
|
||||
///
|
||||
/// assert_eq!(None, bytes.next());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn bytes(&self) -> Bytes {
|
||||
core_str::StrExt::bytes(self)
|
||||
}
|
||||
|
||||
/// Split a string slice by whitespace.
|
||||
///
|
||||
/// The iterator returned will return string slices that are sub-slices of
|
||||
/// the original string slice, separated by any amount of whitespace.
|
||||
///
|
||||
/// 'Whitespace' is defined according to the terms of the Unicode Derived
|
||||
/// Core Property `White_Space`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let mut iter = "A few words".split_whitespace();
|
||||
///
|
||||
/// assert_eq!(Some("A"), iter.next());
|
||||
/// assert_eq!(Some("few"), iter.next());
|
||||
/// assert_eq!(Some("words"), iter.next());
|
||||
///
|
||||
/// assert_eq!(None, iter.next());
|
||||
/// ```
|
||||
///
|
||||
/// All kinds of whitespace are considered:
|
||||
///
|
||||
/// ```
|
||||
/// let mut iter = " Mary had\ta\u{2009}little \n\t lamb".split_whitespace();
|
||||
/// assert_eq!(Some("Mary"), iter.next());
|
||||
/// assert_eq!(Some("had"), iter.next());
|
||||
/// assert_eq!(Some("a"), iter.next());
|
||||
/// assert_eq!(Some("little"), iter.next());
|
||||
/// assert_eq!(Some("lamb"), iter.next());
|
||||
///
|
||||
/// assert_eq!(None, iter.next());
|
||||
/// ```
|
||||
#[stable(feature = "split_whitespace", since = "1.1.0")]
|
||||
#[inline]
|
||||
pub fn split_whitespace(&self) -> SplitWhitespace {
|
||||
UnicodeStr::split_whitespace(self)
|
||||
}
|
||||
|
||||
/// An iterator over the lines of a string, as string slices.
|
||||
///
|
||||
/// Lines are ended with either a newline (`\n`) or a carriage return with
|
||||
/// a line feed (`\r\n`).
|
||||
///
|
||||
/// The final line ending is optional.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let text = "foo\r\nbar\n\nbaz\n";
|
||||
/// let mut lines = text.lines();
|
||||
///
|
||||
/// assert_eq!(Some("foo"), lines.next());
|
||||
/// assert_eq!(Some("bar"), lines.next());
|
||||
/// assert_eq!(Some(""), lines.next());
|
||||
/// assert_eq!(Some("baz"), lines.next());
|
||||
///
|
||||
/// assert_eq!(None, lines.next());
|
||||
/// ```
|
||||
///
|
||||
/// The final line ending isn't required:
|
||||
///
|
||||
/// ```
|
||||
/// let text = "foo\nbar\n\r\nbaz";
|
||||
/// let mut lines = text.lines();
|
||||
///
|
||||
/// assert_eq!(Some("foo"), lines.next());
|
||||
/// assert_eq!(Some("bar"), lines.next());
|
||||
/// assert_eq!(Some(""), lines.next());
|
||||
/// assert_eq!(Some("baz"), lines.next());
|
||||
///
|
||||
/// assert_eq!(None, lines.next());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn lines(&self) -> Lines {
|
||||
core_str::StrExt::lines(self)
|
||||
}
|
||||
|
||||
/// An iterator over the lines of a string.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_deprecated(since = "1.4.0", reason = "use lines() instead now")]
|
||||
#[inline]
|
||||
#[allow(deprecated)]
|
||||
pub fn lines_any(&self) -> LinesAny {
|
||||
core_str::StrExt::lines_any(self)
|
||||
}
|
||||
|
||||
/// Returns an iterator of `u16` over the string encoded as UTF-16.
|
||||
#[stable(feature = "encode_utf16", since = "1.8.0")]
|
||||
pub fn encode_utf16(&self) -> EncodeUtf16 {
|
||||
EncodeUtf16 { encoder: Utf16Encoder::new(self[..].chars()) }
|
||||
}
|
||||
|
||||
/// Returns `true` if the given pattern matches a sub-slice of
|
||||
/// this string slice.
|
||||
///
|
||||
/// Returns `false` if it does not.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let bananas = "bananas";
|
||||
///
|
||||
/// assert!(bananas.contains("nana"));
|
||||
/// assert!(!bananas.contains("apples"));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
|
||||
core_str::StrExt::contains(self, pat)
|
||||
}
|
||||
|
||||
/// Returns `true` if the given pattern matches a prefix of this
|
||||
/// string slice.
|
||||
///
|
||||
/// Returns `false` if it does not.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let bananas = "bananas";
|
||||
///
|
||||
/// assert!(bananas.starts_with("bana"));
|
||||
/// assert!(!bananas.starts_with("nana"));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
|
||||
core_str::StrExt::starts_with(self, pat)
|
||||
}
|
||||
|
||||
/// Returns `true` if the given pattern matches a suffix of this
|
||||
/// string slice.
|
||||
///
|
||||
/// Returns `false` if it does not.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let bananas = "bananas";
|
||||
///
|
||||
/// assert!(bananas.ends_with("anas"));
|
||||
/// assert!(!bananas.ends_with("nana"));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::ends_with(self, pat)
|
||||
}
|
||||
|
||||
/// Returns the byte index of the first character of this string slice that
|
||||
/// matches the pattern.
|
||||
///
|
||||
/// Returns [`None`] if the pattern doesn't match.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines if
|
||||
/// a character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
/// [`None`]: option/enum.Option.html#variant.None
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Simple patterns:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
///
|
||||
/// assert_eq!(s.find('L'), Some(0));
|
||||
/// assert_eq!(s.find('é'), Some(14));
|
||||
/// assert_eq!(s.find("Léopard"), Some(13));
|
||||
/// ```
|
||||
///
|
||||
/// More complex patterns with closures:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
///
|
||||
/// assert_eq!(s.find(char::is_whitespace), Some(5));
|
||||
/// assert_eq!(s.find(char::is_lowercase), Some(1));
|
||||
/// ```
|
||||
///
|
||||
/// Not finding the pattern:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
/// let x: &[_] = &['1', '2'];
|
||||
///
|
||||
/// assert_eq!(s.find(x), None);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
|
||||
core_str::StrExt::find(self, pat)
|
||||
}
|
||||
|
||||
/// Returns the byte index of the last character of this string slice that
|
||||
/// matches the pattern.
|
||||
///
|
||||
/// Returns [`None`] if the pattern doesn't match.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines if
|
||||
/// a character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
/// [`None`]: option/enum.Option.html#variant.None
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Simple patterns:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
///
|
||||
/// assert_eq!(s.rfind('L'), Some(13));
|
||||
/// assert_eq!(s.rfind('é'), Some(14));
|
||||
/// ```
|
||||
///
|
||||
/// More complex patterns with closures:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
///
|
||||
/// assert_eq!(s.rfind(char::is_whitespace), Some(12));
|
||||
/// assert_eq!(s.rfind(char::is_lowercase), Some(20));
|
||||
/// ```
|
||||
///
|
||||
/// Not finding the pattern:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
/// let x: &[_] = &['1', '2'];
|
||||
///
|
||||
/// assert_eq!(s.rfind(x), None);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::rfind(self, pat)
|
||||
}
|
||||
|
||||
/// An iterator over substrings of this string slice, separated by
|
||||
/// characters matched by a pattern.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines the
|
||||
/// split.
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
|
||||
/// allows a reverse search and forward/reverse search yields the same
|
||||
/// elements. This is true for, eg, [`char`] but not for `&str`.
|
||||
///
|
||||
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
|
||||
///
|
||||
/// If the pattern allows a reverse search but its results might differ
|
||||
/// from a forward search, the [`rsplit`] method can be used.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
/// [`rsplit`]: #method.rsplit
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Simple patterns:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
|
||||
/// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "".split('X').collect();
|
||||
/// assert_eq!(v, [""]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect();
|
||||
/// assert_eq!(v, ["lion", "", "tiger", "leopard"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lion::tiger::leopard".split("::").collect();
|
||||
/// assert_eq!(v, ["lion", "tiger", "leopard"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "abc1def2ghi".split(char::is_numeric).collect();
|
||||
/// assert_eq!(v, ["abc", "def", "ghi"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lionXtigerXleopard".split(char::is_uppercase).collect();
|
||||
/// assert_eq!(v, ["lion", "tiger", "leopard"]);
|
||||
/// ```
|
||||
///
|
||||
/// A more complex pattern, using a closure:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "abc1defXghi".split(|c| c == '1' || c == 'X').collect();
|
||||
/// assert_eq!(v, ["abc", "def", "ghi"]);
|
||||
/// ```
|
||||
///
|
||||
/// If a string contains multiple contiguous separators, you will end up
|
||||
/// with empty strings in the output:
|
||||
///
|
||||
/// ```
|
||||
/// let x = "||||a||b|c".to_string();
|
||||
/// let d: Vec<_> = x.split('|').collect();
|
||||
///
|
||||
/// assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]);
|
||||
/// ```
|
||||
///
|
||||
/// Contiguous separators are separated by the empty string.
|
||||
///
|
||||
/// ```
|
||||
/// let x = "(///)".to_string();
|
||||
/// let d: Vec<_> = x.split('/').collect();
|
||||
///
|
||||
/// assert_eq!(d, &["(", "", "", ")"]);
|
||||
/// ```
|
||||
///
|
||||
/// Separators at the start or end of a string are neighbored
|
||||
/// by empty strings.
|
||||
///
|
||||
/// ```
|
||||
/// let d: Vec<_> = "010".split("0").collect();
|
||||
/// assert_eq!(d, &["", "1", ""]);
|
||||
/// ```
|
||||
///
|
||||
/// When the empty string is used as a separator, it separates
|
||||
/// every character in the string, along with the beginning
|
||||
/// and end of the string.
|
||||
///
|
||||
/// ```
|
||||
/// let f: Vec<_> = "rust".split("").collect();
|
||||
/// assert_eq!(f, &["", "r", "u", "s", "t", ""]);
|
||||
/// ```
|
||||
///
|
||||
/// Contiguous separators can lead to possibly surprising behavior
|
||||
/// when whitespace is used as the separator. This code is correct:
|
||||
///
|
||||
/// ```
|
||||
/// let x = " a b c".to_string();
|
||||
/// let d: Vec<_> = x.split(' ').collect();
|
||||
///
|
||||
/// assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]);
|
||||
/// ```
|
||||
///
|
||||
/// It does _not_ give you:
|
||||
///
|
||||
/// ```,ignore
|
||||
/// assert_eq!(d, &["a", "b", "c"]);
|
||||
/// ```
|
||||
///
|
||||
/// Use [`split_whitespace`] for this behavior.
|
||||
///
|
||||
/// [`split_whitespace`]: #method.split_whitespace
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
|
||||
core_str::StrExt::split(self, pat)
|
||||
}
|
||||
|
||||
/// An iterator over substrings of the given string slice, separated by
|
||||
/// characters matched by a pattern and yielded in reverse order.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines the
|
||||
/// split.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator requires that the pattern supports a reverse
|
||||
/// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse
|
||||
/// search yields the same elements.
|
||||
///
|
||||
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
|
||||
///
|
||||
/// For iterating from the front, the [`split`] method can be used.
|
||||
///
|
||||
/// [`split`]: #method.split
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Simple patterns:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "Mary had a little lamb".rsplit(' ').collect();
|
||||
/// assert_eq!(v, ["lamb", "little", "a", "had", "Mary"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "".rsplit('X').collect();
|
||||
/// assert_eq!(v, [""]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lionXXtigerXleopard".rsplit('X').collect();
|
||||
/// assert_eq!(v, ["leopard", "tiger", "", "lion"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lion::tiger::leopard".rsplit("::").collect();
|
||||
/// assert_eq!(v, ["leopard", "tiger", "lion"]);
|
||||
/// ```
|
||||
///
|
||||
/// A more complex pattern, using a closure:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "abc1defXghi".rsplit(|c| c == '1' || c == 'X').collect();
|
||||
/// assert_eq!(v, ["ghi", "def", "abc"]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::rsplit(self, pat)
|
||||
}
|
||||
|
||||
/// An iterator over substrings of the given string slice, separated by
|
||||
/// characters matched by a pattern.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines the
|
||||
/// split.
|
||||
///
|
||||
/// Equivalent to [`split`], except that the trailing substring
|
||||
/// is skipped if empty.
|
||||
///
|
||||
/// [`split`]: #method.split
|
||||
///
|
||||
/// This method can be used for string data that is _terminated_,
|
||||
/// rather than _separated_ by a pattern.
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
|
||||
/// allows a reverse search and forward/reverse search yields the same
|
||||
/// elements. This is true for, eg, [`char`] but not for `&str`.
|
||||
///
|
||||
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// If the pattern allows a reverse search but its results might differ
|
||||
/// from a forward search, the [`rsplit_terminator`] method can be used.
|
||||
///
|
||||
/// [`rsplit_terminator`]: #method.rsplit_terminator
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "A.B.".split_terminator('.').collect();
|
||||
/// assert_eq!(v, ["A", "B"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "A..B..".split_terminator(".").collect();
|
||||
/// assert_eq!(v, ["A", "", "B", ""]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> {
|
||||
core_str::StrExt::split_terminator(self, pat)
|
||||
}
|
||||
|
||||
/// An iterator over substrings of `self`, separated by characters
|
||||
/// matched by a pattern and yielded in reverse order.
|
||||
///
|
||||
/// The pattern can be a simple `&str`, [`char`], or a closure that
|
||||
/// determines the split.
|
||||
/// Additional libraries might provide more complex patterns like
|
||||
/// regular expressions.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// Equivalent to [`split`], except that the trailing substring is
|
||||
/// skipped if empty.
|
||||
///
|
||||
/// [`split`]: #method.split
|
||||
///
|
||||
/// This method can be used for string data that is _terminated_,
|
||||
/// rather than _separated_ by a pattern.
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator requires that the pattern supports a
|
||||
/// reverse search, and it will be double ended if a forward/reverse
|
||||
/// search yields the same elements.
|
||||
///
|
||||
/// For iterating from the front, the [`split_terminator`] method can be
|
||||
/// used.
|
||||
///
|
||||
/// [`split_terminator`]: #method.split_terminator
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "A.B.".rsplit_terminator('.').collect();
|
||||
/// assert_eq!(v, ["B", "A"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "A..B..".rsplit_terminator(".").collect();
|
||||
/// assert_eq!(v, ["", "B", "", "A"]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::rsplit_terminator(self, pat)
|
||||
}
|
||||
|
||||
/// An iterator over substrings of the given string slice, separated by a
|
||||
/// pattern, restricted to returning at most `n` items.
|
||||
///
|
||||
/// If `n` substrings are returned, the last substring (the `n`th substring)
|
||||
/// will contain the remainder of the string.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines the
|
||||
/// split.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator will not be double ended, because it is
|
||||
/// not efficient to support.
|
||||
///
|
||||
/// If the pattern allows a reverse search, the [`rsplitn`] method can be
|
||||
/// used.
|
||||
///
|
||||
/// [`rsplitn`]: #method.rsplitn
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Simple patterns:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "Mary had a little lambda".splitn(3, ' ').collect();
|
||||
/// assert_eq!(v, ["Mary", "had", "a little lambda"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lionXXtigerXleopard".splitn(3, "X").collect();
|
||||
/// assert_eq!(v, ["lion", "", "tigerXleopard"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "abcXdef".splitn(1, 'X').collect();
|
||||
/// assert_eq!(v, ["abcXdef"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "".splitn(1, 'X').collect();
|
||||
/// assert_eq!(v, [""]);
|
||||
/// ```
|
||||
///
|
||||
/// A more complex pattern, using a closure:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "abc1defXghi".splitn(2, |c| c == '1' || c == 'X').collect();
|
||||
/// assert_eq!(v, ["abc", "defXghi"]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn splitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> SplitN<'a, P> {
|
||||
core_str::StrExt::splitn(self, n, pat)
|
||||
}
|
||||
|
||||
/// An iterator over substrings of this string slice, separated by a
|
||||
/// pattern, starting from the end of the string, restricted to returning
|
||||
/// at most `n` items.
|
||||
///
|
||||
/// If `n` substrings are returned, the last substring (the `n`th substring)
|
||||
/// will contain the remainder of the string.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that
|
||||
/// determines the split.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator will not be double ended, because it is not
|
||||
/// efficient to support.
|
||||
///
|
||||
/// For splitting from the front, the [`splitn`] method can be used.
|
||||
///
|
||||
/// [`splitn`]: #method.splitn
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Simple patterns:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "Mary had a little lamb".rsplitn(3, ' ').collect();
|
||||
/// assert_eq!(v, ["lamb", "little", "Mary had a"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(3, 'X').collect();
|
||||
/// assert_eq!(v, ["leopard", "tiger", "lionX"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lion::tiger::leopard".rsplitn(2, "::").collect();
|
||||
/// assert_eq!(v, ["leopard", "lion::tiger"]);
|
||||
/// ```
|
||||
///
|
||||
/// A more complex pattern, using a closure:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "abc1defXghi".rsplitn(2, |c| c == '1' || c == 'X').collect();
|
||||
/// assert_eq!(v, ["ghi", "abc1def"]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> RSplitN<'a, P>
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::rsplitn(self, n, pat)
|
||||
}
|
||||
|
||||
/// An iterator over the disjoint matches of a pattern within the given string
|
||||
/// slice.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that
|
||||
/// determines if a character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
|
||||
/// allows a reverse search and forward/reverse search yields the same
|
||||
/// elements. This is true for, eg, [`char`] but not for `&str`.
|
||||
///
|
||||
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// If the pattern allows a reverse search but its results might differ
|
||||
/// from a forward search, the [`rmatches`] method can be used.
|
||||
///
|
||||
/// [`rmatches`]: #method.rmatches
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "abcXXXabcYYYabc".matches("abc").collect();
|
||||
/// assert_eq!(v, ["abc", "abc", "abc"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "1abc2abc3".matches(char::is_numeric).collect();
|
||||
/// assert_eq!(v, ["1", "2", "3"]);
|
||||
/// ```
|
||||
#[stable(feature = "str_matches", since = "1.2.0")]
|
||||
#[inline]
|
||||
pub fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> {
|
||||
core_str::StrExt::matches(self, pat)
|
||||
}
|
||||
|
||||
/// An iterator over the disjoint matches of a pattern within this string slice,
|
||||
/// yielded in reverse order.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines if
|
||||
/// a character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator requires that the pattern supports a reverse
|
||||
/// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse
|
||||
/// search yields the same elements.
|
||||
///
|
||||
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
|
||||
///
|
||||
/// For iterating from the front, the [`matches`] method can be used.
|
||||
///
|
||||
/// [`matches`]: #method.matches
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "abcXXXabcYYYabc".rmatches("abc").collect();
|
||||
/// assert_eq!(v, ["abc", "abc", "abc"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "1abc2abc3".rmatches(char::is_numeric).collect();
|
||||
/// assert_eq!(v, ["3", "2", "1"]);
|
||||
/// ```
|
||||
#[stable(feature = "str_matches", since = "1.2.0")]
|
||||
#[inline]
|
||||
pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::rmatches(self, pat)
|
||||
}
|
||||
|
||||
/// An iterator over the disjoint matches of a pattern within this string
|
||||
/// slice as well as the index that the match starts at.
|
||||
///
|
||||
/// For matches of `pat` within `self` that overlap, only the indices
|
||||
/// corresponding to the first match are returned.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines
|
||||
/// if a character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
|
||||
/// allows a reverse search and forward/reverse search yields the same
|
||||
/// elements. This is true for, eg, [`char`] but not for `&str`.
|
||||
///
|
||||
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
|
||||
///
|
||||
/// If the pattern allows a reverse search but its results might differ
|
||||
/// from a forward search, the [`rmatch_indices`] method can be used.
|
||||
///
|
||||
/// [`rmatch_indices`]: #method.rmatch_indices
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<_> = "abcXXXabcYYYabc".match_indices("abc").collect();
|
||||
/// assert_eq!(v, [(0, "abc"), (6, "abc"), (12, "abc")]);
|
||||
///
|
||||
/// let v: Vec<_> = "1abcabc2".match_indices("abc").collect();
|
||||
/// assert_eq!(v, [(1, "abc"), (4, "abc")]);
|
||||
///
|
||||
/// let v: Vec<_> = "ababa".match_indices("aba").collect();
|
||||
/// assert_eq!(v, [(0, "aba")]); // only the first `aba`
|
||||
/// ```
|
||||
#[stable(feature = "str_match_indices", since = "1.5.0")]
|
||||
#[inline]
|
||||
pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
|
||||
core_str::StrExt::match_indices(self, pat)
|
||||
}
|
||||
|
||||
/// An iterator over the disjoint matches of a pattern within `self`,
|
||||
/// yielded in reverse order along with the index of the match.
|
||||
///
|
||||
/// For matches of `pat` within `self` that overlap, only the indices
|
||||
/// corresponding to the last match are returned.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines if a
|
||||
/// character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator requires that the pattern supports a reverse
|
||||
/// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse
|
||||
/// search yields the same elements.
|
||||
///
|
||||
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
|
||||
///
|
||||
/// For iterating from the front, the [`match_indices`] method can be used.
|
||||
///
|
||||
/// [`match_indices`]: #method.match_indices
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<_> = "abcXXXabcYYYabc".rmatch_indices("abc").collect();
|
||||
/// assert_eq!(v, [(12, "abc"), (6, "abc"), (0, "abc")]);
|
||||
///
|
||||
/// let v: Vec<_> = "1abcabc2".rmatch_indices("abc").collect();
|
||||
/// assert_eq!(v, [(4, "abc"), (1, "abc")]);
|
||||
///
|
||||
/// let v: Vec<_> = "ababa".rmatch_indices("aba").collect();
|
||||
/// assert_eq!(v, [(2, "aba")]); // only the last `aba`
|
||||
/// ```
|
||||
#[stable(feature = "str_match_indices", since = "1.5.0")]
|
||||
#[inline]
|
||||
pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::rmatch_indices(self, pat)
|
||||
}
|
||||
|
||||
/// Returns a string slice with leading and trailing whitespace removed.
|
||||
///
|
||||
/// 'Whitespace' is defined according to the terms of the Unicode Derived
|
||||
/// Core Property `White_Space`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = " Hello\tworld\t";
|
||||
///
|
||||
/// assert_eq!("Hello\tworld", s.trim());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn trim(&self) -> &str {
|
||||
UnicodeStr::trim(self)
|
||||
}
|
||||
|
||||
/// Returns a string slice with leading whitespace removed.
|
||||
///
|
||||
/// 'Whitespace' is defined according to the terms of the Unicode Derived
|
||||
/// Core Property `White_Space`.
|
||||
///
|
||||
/// # Text directionality
|
||||
///
|
||||
/// A string is a sequence of bytes. 'Left' in this context means the first
|
||||
/// position of that byte string; for a language like Arabic or Hebrew
|
||||
/// which are 'right to left' rather than 'left to right', this will be
|
||||
/// the _right_ side, not the left.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = " Hello\tworld\t";
|
||||
///
|
||||
/// assert_eq!("Hello\tworld\t", s.trim_left());
|
||||
/// ```
|
||||
///
|
||||
/// Directionality:
|
||||
///
|
||||
/// ```
|
||||
/// let s = " English";
|
||||
/// assert!(Some('E') == s.trim_left().chars().next());
|
||||
///
|
||||
/// let s = " עברית";
|
||||
/// assert!(Some('ע') == s.trim_left().chars().next());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn trim_left(&self) -> &str {
|
||||
UnicodeStr::trim_left(self)
|
||||
}
|
||||
|
||||
/// Returns a string slice with trailing whitespace removed.
|
||||
///
|
||||
/// 'Whitespace' is defined according to the terms of the Unicode Derived
|
||||
/// Core Property `White_Space`.
|
||||
///
|
||||
/// # Text directionality
|
||||
///
|
||||
/// A string is a sequence of bytes. 'Right' in this context means the last
|
||||
/// position of that byte string; for a language like Arabic or Hebrew
|
||||
/// which are 'right to left' rather than 'left to right', this will be
|
||||
/// the _left_ side, not the right.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = " Hello\tworld\t";
|
||||
///
|
||||
/// assert_eq!(" Hello\tworld", s.trim_right());
|
||||
/// ```
|
||||
///
|
||||
/// Directionality:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "English ";
|
||||
/// assert!(Some('h') == s.trim_right().chars().rev().next());
|
||||
///
|
||||
/// let s = "עברית ";
|
||||
/// assert!(Some('ת') == s.trim_right().chars().rev().next());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn trim_right(&self) -> &str {
|
||||
UnicodeStr::trim_right(self)
|
||||
}
|
||||
|
||||
/// Returns a string slice with all prefixes and suffixes that match a
|
||||
/// pattern repeatedly removed.
|
||||
///
|
||||
/// The pattern can be a [`char`] or a closure that determines if a
|
||||
/// character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Simple patterns:
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
|
||||
/// assert_eq!("123foo1bar123".trim_matches(char::is_numeric), "foo1bar");
|
||||
///
|
||||
/// let x: &[_] = &['1', '2'];
|
||||
/// assert_eq!("12foo1bar12".trim_matches(x), "foo1bar");
|
||||
/// ```
|
||||
///
|
||||
/// A more complex pattern, using a closure:
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!("1foo1barXX".trim_matches(|c| c == '1' || c == 'X'), "foo1bar");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
|
||||
where P::Searcher: DoubleEndedSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::trim_matches(self, pat)
|
||||
}
|
||||
|
||||
/// Returns a string slice with all prefixes that match a pattern
|
||||
/// repeatedly removed.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines if
|
||||
/// a character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Text directionality
|
||||
///
|
||||
/// A string is a sequence of bytes. 'Left' in this context means the first
|
||||
/// position of that byte string; for a language like Arabic or Hebrew
|
||||
/// which are 'right to left' rather than 'left to right', this will be
|
||||
/// the _right_ side, not the left.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
|
||||
/// assert_eq!("123foo1bar123".trim_left_matches(char::is_numeric), "foo1bar123");
|
||||
///
|
||||
/// let x: &[_] = &['1', '2'];
|
||||
/// assert_eq!("12foo1bar12".trim_left_matches(x), "foo1bar12");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
|
||||
core_str::StrExt::trim_left_matches(self, pat)
|
||||
}
|
||||
|
||||
/// Returns a string slice with all suffixes that match a pattern
|
||||
/// repeatedly removed.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that
|
||||
/// determines if a character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Text directionality
|
||||
///
|
||||
/// A string is a sequence of bytes. 'Right' in this context means the last
|
||||
/// position of that byte string; for a language like Arabic or Hebrew
|
||||
/// which are 'right to left' rather than 'left to right', this will be
|
||||
/// the _left_ side, not the right.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Simple patterns:
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
|
||||
/// assert_eq!("123foo1bar123".trim_right_matches(char::is_numeric), "123foo1bar");
|
||||
///
|
||||
/// let x: &[_] = &['1', '2'];
|
||||
/// assert_eq!("12foo1bar12".trim_right_matches(x), "12foo1bar");
|
||||
/// ```
|
||||
///
|
||||
/// A more complex pattern, using a closure:
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!("1fooX".trim_left_matches(|c| c == '1' || c == 'X'), "fooX");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::trim_right_matches(self, pat)
|
||||
}
|
||||
|
||||
/// Parses this string slice into another type.
|
||||
///
|
||||
/// Because `parse` is so general, it can cause problems with type
|
||||
/// inference. As such, `parse` is one of the few times you'll see
|
||||
/// the syntax affectionately known as the 'turbofish': `::<>`. This
|
||||
/// helps the inference algorithm understand specifically which type
|
||||
/// you're trying to parse into.
|
||||
///
|
||||
/// `parse` can parse any type that implements the [`FromStr`] trait.
|
||||
///
|
||||
/// [`FromStr`]: str/trait.FromStr.html
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Will return [`Err`] if it's not possible to parse this string slice into
|
||||
/// the desired type.
|
||||
///
|
||||
/// [`Err`]: str/trait.FromStr.html#associatedtype.Err
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Basic usage
|
||||
///
|
||||
/// ```
|
||||
/// let four: u32 = "4".parse().unwrap();
|
||||
///
|
||||
/// assert_eq!(4, four);
|
||||
/// ```
|
||||
///
|
||||
/// Using the 'turbofish' instead of annotating `four`:
|
||||
///
|
||||
/// ```
|
||||
/// let four = "4".parse::<u32>();
|
||||
///
|
||||
/// assert_eq!(Ok(4), four);
|
||||
/// ```
|
||||
///
|
||||
/// Failing to parse:
|
||||
///
|
||||
/// ```
|
||||
/// let nope = "j".parse::<u32>();
|
||||
///
|
||||
/// assert!(nope.is_err());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
|
||||
core_str::StrExt::parse(self)
|
||||
}
|
||||
|
||||
/// Converts a `Box<str>` into a `Box<[u8]>` without copying or allocating.
|
||||
#[unstable(feature = "str_box_extras", issue = "41119")]
|
||||
pub fn into_boxed_bytes(self: Box<str>) -> Box<[u8]> {
|
||||
self.into()
|
||||
}
|
||||
|
||||
/// Replaces all matches of a pattern with another string.
|
||||
///
|
||||
/// `replace` creates a new [`String`], and copies the data from this string slice into it.
|
||||
/// While doing so, it attempts to find matches of a pattern. If it finds any, it
|
||||
/// replaces them with the replacement string slice.
|
||||
///
|
||||
/// [`String`]: string/struct.String.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "this is old";
|
||||
///
|
||||
/// assert_eq!("this is new", s.replace("old", "new"));
|
||||
/// ```
|
||||
///
|
||||
/// When the pattern doesn't match:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "this is old";
|
||||
/// assert_eq!(s, s.replace("cookie monster", "little lamb"));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn replace<'a, P: Pattern<'a>>(&'a self, from: P, to: &str) -> String {
|
||||
let mut result = String::new();
|
||||
let mut last_end = 0;
|
||||
for (start, part) in self.match_indices(from) {
|
||||
result.push_str(unsafe { self.slice_unchecked(last_end, start) });
|
||||
result.push_str(to);
|
||||
last_end = start + part.len();
|
||||
}
|
||||
result.push_str(unsafe { self.slice_unchecked(last_end, self.len()) });
|
||||
result
|
||||
}
|
||||
|
||||
/// Replaces first N matches of a pattern with another string.
|
||||
///
|
||||
/// `replacen` creates a new [`String`], and copies the data from this string slice into it.
|
||||
/// While doing so, it attempts to find matches of a pattern. If it finds any, it
|
||||
/// replaces them with the replacement string slice at most `count` times.
|
||||
///
|
||||
/// [`String`]: string/struct.String.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "foo foo 123 foo";
|
||||
/// assert_eq!("new new 123 foo", s.replacen("foo", "new", 2));
|
||||
/// assert_eq!("faa fao 123 foo", s.replacen('o', "a", 3));
|
||||
/// assert_eq!("foo foo new23 foo", s.replacen(char::is_numeric, "new", 1));
|
||||
/// ```
|
||||
///
|
||||
/// When the pattern doesn't match:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "this is old";
|
||||
/// assert_eq!(s, s.replacen("cookie monster", "little lamb", 10));
|
||||
/// ```
|
||||
#[stable(feature = "str_replacen", since = "1.16.0")]
|
||||
pub fn replacen<'a, P: Pattern<'a>>(&'a self, pat: P, to: &str, count: usize) -> String {
|
||||
// Hope to reduce the times of re-allocation
|
||||
let mut result = String::with_capacity(32);
|
||||
let mut last_end = 0;
|
||||
for (start, part) in self.match_indices(pat).take(count) {
|
||||
result.push_str(unsafe { self.slice_unchecked(last_end, start) });
|
||||
result.push_str(to);
|
||||
last_end = start + part.len();
|
||||
}
|
||||
result.push_str(unsafe { self.slice_unchecked(last_end, self.len()) });
|
||||
result
|
||||
}
|
||||
|
||||
/// Returns the lowercase equivalent of this string slice, as a new [`String`].
|
||||
///
|
||||
/// 'Lowercase' is defined according to the terms of the Unicode Derived Core Property
|
||||
/// `Lowercase`.
|
||||
///
|
||||
/// Since some characters can expand into multiple characters when changing
|
||||
/// the case, this function returns a [`String`] instead of modifying the
|
||||
/// parameter in-place.
|
||||
///
|
||||
/// [`String`]: string/struct.String.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "HELLO";
|
||||
///
|
||||
/// assert_eq!("hello", s.to_lowercase());
|
||||
/// ```
|
||||
///
|
||||
/// A tricky example, with sigma:
|
||||
///
|
||||
/// ```
|
||||
/// let sigma = "Σ";
|
||||
///
|
||||
/// assert_eq!("σ", sigma.to_lowercase());
|
||||
///
|
||||
/// // but at the end of a word, it's ς, not σ:
|
||||
/// let odysseus = "ὈΔΥΣΣΕΎΣ";
|
||||
///
|
||||
/// assert_eq!("ὀδυσσεύς", odysseus.to_lowercase());
|
||||
/// ```
|
||||
///
|
||||
/// Languages without case are not changed:
|
||||
///
|
||||
/// ```
|
||||
/// let new_year = "农历新年";
|
||||
///
|
||||
/// assert_eq!(new_year, new_year.to_lowercase());
|
||||
/// ```
|
||||
#[stable(feature = "unicode_case_mapping", since = "1.2.0")]
|
||||
pub fn to_lowercase(&self) -> String {
|
||||
let mut s = String::with_capacity(self.len());
|
||||
for (i, c) in self[..].char_indices() {
|
||||
if c == 'Σ' {
|
||||
// Σ maps to σ, except at the end of a word where it maps to ς.
|
||||
// This is the only conditional (contextual) but language-independent mapping
|
||||
// in `SpecialCasing.txt`,
|
||||
// so hard-code it rather than have a generic "condition" mechanism.
|
||||
// See https://github.com/rust-lang/rust/issues/26035
|
||||
map_uppercase_sigma(self, i, &mut s)
|
||||
} else {
|
||||
s.extend(c.to_lowercase());
|
||||
}
|
||||
}
|
||||
return s;
|
||||
|
||||
fn map_uppercase_sigma(from: &str, i: usize, to: &mut String) {
|
||||
// See http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992
|
||||
// for the definition of `Final_Sigma`.
|
||||
debug_assert!('Σ'.len_utf8() == 2);
|
||||
let is_word_final = case_ignoreable_then_cased(from[..i].chars().rev()) &&
|
||||
!case_ignoreable_then_cased(from[i + 2..].chars());
|
||||
to.push_str(if is_word_final { "ς" } else { "σ" });
|
||||
}
|
||||
|
||||
fn case_ignoreable_then_cased<I: Iterator<Item = char>>(iter: I) -> bool {
|
||||
use std_unicode::derived_property::{Cased, Case_Ignorable};
|
||||
match iter.skip_while(|&c| Case_Ignorable(c)).next() {
|
||||
Some(c) => Cased(c),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the uppercase equivalent of this string slice, as a new [`String`].
|
||||
///
|
||||
/// 'Uppercase' is defined according to the terms of the Unicode Derived Core Property
|
||||
/// `Uppercase`.
|
||||
///
|
||||
/// Since some characters can expand into multiple characters when changing
|
||||
/// the case, this function returns a [`String`] instead of modifying the
|
||||
/// parameter in-place.
|
||||
///
|
||||
/// [`String`]: string/struct.String.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "hello";
|
||||
///
|
||||
/// assert_eq!("HELLO", s.to_uppercase());
|
||||
/// ```
|
||||
///
|
||||
/// Scripts without case are not changed:
|
||||
///
|
||||
/// ```
|
||||
/// let new_year = "农历新年";
|
||||
///
|
||||
/// assert_eq!(new_year, new_year.to_uppercase());
|
||||
/// ```
|
||||
#[stable(feature = "unicode_case_mapping", since = "1.2.0")]
|
||||
pub fn to_uppercase(&self) -> String {
|
||||
let mut s = String::with_capacity(self.len());
|
||||
s.extend(self.chars().flat_map(|c| c.to_uppercase()));
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Escapes each char in `s` with [`char::escape_debug`].
|
||||
///
|
||||
/// [`char::escape_debug`]: primitive.char.html#method.escape_debug
|
||||
#[unstable(feature = "str_escape",
|
||||
reason = "return type may change to be an iterator",
|
||||
issue = "27791")]
|
||||
pub fn escape_debug(&self) -> String {
|
||||
self.chars().flat_map(|c| c.escape_debug()).collect()
|
||||
}
|
||||
|
||||
/// Escapes each char in `s` with [`char::escape_default`].
|
||||
///
|
||||
/// [`char::escape_default`]: primitive.char.html#method.escape_default
|
||||
#[unstable(feature = "str_escape",
|
||||
reason = "return type may change to be an iterator",
|
||||
issue = "27791")]
|
||||
pub fn escape_default(&self) -> String {
|
||||
self.chars().flat_map(|c| c.escape_default()).collect()
|
||||
}
|
||||
|
||||
/// Escapes each char in `s` with [`char::escape_unicode`].
|
||||
///
|
||||
/// [`char::escape_unicode`]: primitive.char.html#method.escape_unicode
|
||||
#[unstable(feature = "str_escape",
|
||||
reason = "return type may change to be an iterator",
|
||||
issue = "27791")]
|
||||
pub fn escape_unicode(&self) -> String {
|
||||
self.chars().flat_map(|c| c.escape_unicode()).collect()
|
||||
}
|
||||
|
||||
/// Converts a [`Box<str>`] into a [`String`] without copying or allocating.
|
||||
///
|
||||
/// [`String`]: string/struct.String.html
|
||||
/// [`Box<str>`]: boxed/struct.Box.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let string = String::from("birthday gift");
|
||||
/// let boxed_str = string.clone().into_boxed_str();
|
||||
///
|
||||
/// assert_eq!(boxed_str.into_string(), string);
|
||||
/// ```
|
||||
#[stable(feature = "box_str", since = "1.4.0")]
|
||||
pub fn into_string(self: Box<str>) -> String {
|
||||
unsafe {
|
||||
let slice = mem::transmute::<Box<str>, Box<[u8]>>(self);
|
||||
String::from_utf8_unchecked(slice.into_vec())
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a [`String`] by repeating a string `n` times.
|
||||
///
|
||||
/// [`String`]: string/struct.String.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!("abc".repeat(4), String::from("abcabcabcabc"));
|
||||
/// ```
|
||||
#[stable(feature = "repeat_str", since = "1.16.0")]
|
||||
pub fn repeat(&self, n: usize) -> String {
|
||||
let mut s = String::with_capacity(self.len() * n);
|
||||
s.extend((0..n).map(|_| self));
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts a boxed slice of bytes to a boxed string slice without checking
|
||||
/// that the string contains valid UTF-8.
|
||||
#[unstable(feature = "str_box_extras", issue = "41119")]
|
||||
|
||||
@@ -56,8 +56,6 @@
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use alloc::str as alloc_str;
|
||||
|
||||
use core::fmt;
|
||||
use core::hash;
|
||||
use core::iter::{FromIterator, FusedIterator};
|
||||
@@ -70,7 +68,7 @@
|
||||
use borrow::{Cow, ToOwned};
|
||||
use range::RangeArgument;
|
||||
use Bound::{Excluded, Included, Unbounded};
|
||||
use str::{self, FromStr, Utf8Error, Chars};
|
||||
use str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars};
|
||||
use vec::Vec;
|
||||
use boxed::Box;
|
||||
|
||||
@@ -1464,7 +1462,7 @@ pub fn splice<'a, 'b, R>(&'a mut self, range: R, replace_with: &'b str) -> Splic
|
||||
#[stable(feature = "box_str", since = "1.4.0")]
|
||||
pub fn into_boxed_str(self) -> Box<str> {
|
||||
let slice = self.vec.into_boxed_slice();
|
||||
unsafe { alloc_str::from_boxed_utf8_unchecked(slice) }
|
||||
unsafe { from_boxed_utf8_unchecked(slice) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
|
||||
#![deny(warnings)]
|
||||
|
||||
#![feature(alloc)]
|
||||
#![feature(attr_literals)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(inclusive_range_syntax)]
|
||||
#![feature(collection_placement)]
|
||||
#![feature(collections)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(exact_size_is_empty)]
|
||||
#![feature(iterator_step_by)]
|
||||
@@ -31,7 +31,7 @@
|
||||
#![feature(unicode)]
|
||||
#![feature(utf8_error_error_len)]
|
||||
|
||||
extern crate collections;
|
||||
extern crate alloc;
|
||||
extern crate test;
|
||||
extern crate std_unicode;
|
||||
extern crate core;
|
||||
@@ -66,10 +66,6 @@
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use alloc::raw_vec::RawVec;
|
||||
use borrow::ToOwned;
|
||||
use borrow::Cow;
|
||||
use core::cmp::Ordering;
|
||||
use core::fmt;
|
||||
use core::hash::{self, Hash};
|
||||
@@ -84,6 +80,10 @@
|
||||
use core::ptr::Shared;
|
||||
use core::slice;
|
||||
|
||||
use borrow::ToOwned;
|
||||
use borrow::Cow;
|
||||
use boxed::Box;
|
||||
use raw_vec::RawVec;
|
||||
use super::range::RangeArgument;
|
||||
use Bound::{Excluded, Included, Unbounded};
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
use core::hash::{Hash, Hasher};
|
||||
use core::cmp;
|
||||
|
||||
use alloc::raw_vec::RawVec;
|
||||
use raw_vec::RawVec;
|
||||
|
||||
use super::range::RangeArgument;
|
||||
use Bound::{Excluded, Included, Unbounded};
|
||||
@@ -1,21 +0,0 @@
|
||||
[package]
|
||||
authors = ["The Rust Project Developers"]
|
||||
name = "collections"
|
||||
version = "0.0.0"
|
||||
|
||||
[lib]
|
||||
name = "collections"
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
alloc = { path = "../liballoc" }
|
||||
core = { path = "../libcore" }
|
||||
std_unicode = { path = "../libstd_unicode" }
|
||||
|
||||
[[test]]
|
||||
name = "collectionstests"
|
||||
path = "../libcollections/tests/lib.rs"
|
||||
|
||||
[[bench]]
|
||||
name = "collectionsbenches"
|
||||
path = "../libcollections/benches/lib.rs"
|
||||
@@ -1,192 +0,0 @@
|
||||
// Copyright 2013-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.
|
||||
|
||||
//! Collection types.
|
||||
//!
|
||||
//! See [`std::collections`](../std/collections/index.html) for a detailed
|
||||
//! discussion of collections in Rust.
|
||||
|
||||
#![crate_name = "collections"]
|
||||
#![crate_type = "rlib"]
|
||||
#![unstable(feature = "collections",
|
||||
reason = "library is unlikely to be stabilized with the current \
|
||||
layout and name, use std::collections instead",
|
||||
issue = "27783")]
|
||||
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
|
||||
html_root_url = "https://doc.rust-lang.org/nightly/",
|
||||
html_playground_url = "https://play.rust-lang.org/",
|
||||
issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
|
||||
test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
|
||||
|
||||
#![cfg_attr(test, allow(deprecated))] // rand
|
||||
#![deny(warnings)]
|
||||
#![deny(missing_debug_implementations)]
|
||||
|
||||
#![feature(alloc)]
|
||||
#![feature(allow_internal_unstable)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(box_syntax)]
|
||||
#![cfg_attr(not(test), feature(char_escape_debug))]
|
||||
#![cfg_attr(not(test), feature(core_float))]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(dropck_eyepatch)]
|
||||
#![feature(exact_size_is_empty)]
|
||||
#![feature(fmt_internals)]
|
||||
#![feature(fused)]
|
||||
#![feature(generic_param_attrs)]
|
||||
#![feature(heap_api)]
|
||||
#![feature(i128_type)]
|
||||
#![feature(inclusive_range)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(manually_drop)]
|
||||
#![feature(nonzero)]
|
||||
#![feature(pattern)]
|
||||
#![feature(placement_in)]
|
||||
#![feature(placement_in_syntax)]
|
||||
#![feature(placement_new_protocol)]
|
||||
#![feature(shared)]
|
||||
#![feature(slice_get_slice)]
|
||||
#![feature(slice_patterns)]
|
||||
#![cfg_attr(not(test), feature(slice_rotate))]
|
||||
#![feature(slice_rsplit)]
|
||||
#![cfg_attr(not(test), feature(sort_unstable))]
|
||||
#![feature(specialization)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(str_internals)]
|
||||
#![feature(str_box_extras)]
|
||||
#![feature(str_mut_extras)]
|
||||
#![feature(trusted_len)]
|
||||
#![feature(unicode)]
|
||||
#![feature(unique)]
|
||||
#![cfg_attr(not(test), feature(str_checked_slicing))]
|
||||
#![cfg_attr(test, feature(rand, test))]
|
||||
#![feature(offset_to)]
|
||||
|
||||
#![no_std]
|
||||
|
||||
extern crate std_unicode;
|
||||
extern crate alloc;
|
||||
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
extern crate std;
|
||||
#[cfg(test)]
|
||||
extern crate test;
|
||||
|
||||
#[doc(no_inline)]
|
||||
pub use binary_heap::BinaryHeap;
|
||||
#[doc(no_inline)]
|
||||
pub use btree_map::BTreeMap;
|
||||
#[doc(no_inline)]
|
||||
pub use btree_set::BTreeSet;
|
||||
#[doc(no_inline)]
|
||||
pub use linked_list::LinkedList;
|
||||
#[doc(no_inline)]
|
||||
pub use vec_deque::VecDeque;
|
||||
#[doc(no_inline)]
|
||||
pub use string::String;
|
||||
#[doc(no_inline)]
|
||||
pub use vec::Vec;
|
||||
|
||||
// Needed for the vec! macro
|
||||
pub use alloc::boxed;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
pub mod binary_heap;
|
||||
mod btree;
|
||||
pub mod borrow;
|
||||
pub mod fmt;
|
||||
pub mod linked_list;
|
||||
pub mod range;
|
||||
pub mod slice;
|
||||
pub mod str;
|
||||
pub mod string;
|
||||
pub mod vec;
|
||||
pub mod vec_deque;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub mod btree_map {
|
||||
//! A map based on a B-Tree.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use btree::map::*;
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub mod btree_set {
|
||||
//! A set based on a B-Tree.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use btree::set::*;
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
mod std {
|
||||
pub use core::ops; // RangeFull
|
||||
}
|
||||
|
||||
/// An endpoint of a range of keys.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// `Bound`s are range endpoints:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(collections_range)]
|
||||
///
|
||||
/// use std::collections::range::RangeArgument;
|
||||
/// use std::collections::Bound::*;
|
||||
///
|
||||
/// assert_eq!((..100).start(), Unbounded);
|
||||
/// assert_eq!((1..12).start(), Included(&1));
|
||||
/// assert_eq!((1..12).end(), Excluded(&12));
|
||||
/// ```
|
||||
///
|
||||
/// Using a tuple of `Bound`s as an argument to [`BTreeMap::range`].
|
||||
/// Note that in most cases, it's better to use range syntax (`1..5`) instead.
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::BTreeMap;
|
||||
/// use std::collections::Bound::{Excluded, Included, Unbounded};
|
||||
///
|
||||
/// let mut map = BTreeMap::new();
|
||||
/// map.insert(3, "a");
|
||||
/// map.insert(5, "b");
|
||||
/// map.insert(8, "c");
|
||||
///
|
||||
/// for (key, value) in map.range((Excluded(3), Included(8))) {
|
||||
/// println!("{}: {}", key, value);
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(Some((&3, &"a")), map.range((Unbounded, Included(5))).next());
|
||||
/// ```
|
||||
///
|
||||
/// [`BTreeMap::range`]: btree_map/struct.BTreeMap.html#method.range
|
||||
#[stable(feature = "collections_bound", since = "1.17.0")]
|
||||
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
|
||||
pub enum Bound<T> {
|
||||
/// An inclusive bound.
|
||||
#[stable(feature = "collections_bound", since = "1.17.0")]
|
||||
Included(T),
|
||||
/// An exclusive bound.
|
||||
#[stable(feature = "collections_bound", since = "1.17.0")]
|
||||
Excluded(T),
|
||||
/// An infinite endpoint. Indicates that there is no bound in this direction.
|
||||
#[stable(feature = "collections_bound", since = "1.17.0")]
|
||||
Unbounded,
|
||||
}
|
||||
|
||||
/// An intermediate trait for specialization of `Extend`.
|
||||
#[doc(hidden)]
|
||||
trait SpecExtend<I: IntoIterator> {
|
||||
/// Extends `self` with the contents of the given iterator.
|
||||
fn spec_extend(&mut self, iter: I);
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
// Copyright 2014-2015 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.
|
||||
|
||||
/// Creates a `Vec` containing the arguments.
|
||||
///
|
||||
/// `vec!` allows `Vec`s to be defined with the same syntax as array expressions.
|
||||
/// There are two forms of this macro:
|
||||
///
|
||||
/// - Create a `Vec` containing a given list of elements:
|
||||
///
|
||||
/// ```
|
||||
/// let v = vec![1, 2, 3];
|
||||
/// assert_eq!(v[0], 1);
|
||||
/// assert_eq!(v[1], 2);
|
||||
/// assert_eq!(v[2], 3);
|
||||
/// ```
|
||||
///
|
||||
/// - Create a `Vec` from a given element and size:
|
||||
///
|
||||
/// ```
|
||||
/// let v = vec![1; 3];
|
||||
/// assert_eq!(v, [1, 1, 1]);
|
||||
/// ```
|
||||
///
|
||||
/// Note that unlike array expressions this syntax supports all elements
|
||||
/// which implement `Clone` and the number of elements doesn't have to be
|
||||
/// a constant.
|
||||
///
|
||||
/// This will use `clone()` to duplicate an expression, so one should be careful
|
||||
/// using this with types having a nonstandard `Clone` implementation. For
|
||||
/// example, `vec![Rc::new(1); 5]` will create a vector of five references
|
||||
/// to the same boxed integer value, not five references pointing to independently
|
||||
/// boxed integers.
|
||||
#[cfg(not(test))]
|
||||
#[macro_export]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[allow_internal_unstable]
|
||||
macro_rules! vec {
|
||||
($elem:expr; $n:expr) => (
|
||||
$crate::vec::from_elem($elem, $n)
|
||||
);
|
||||
($($x:expr),*) => (
|
||||
<[_]>::into_vec(box [$($x),*])
|
||||
);
|
||||
($($x:expr,)*) => (vec![$($x),*])
|
||||
}
|
||||
|
||||
// HACK(japaric): with cfg(test) the inherent `[T]::into_vec` method, which is
|
||||
// required for this macro definition, is not available. Instead use the
|
||||
// `slice::into_vec` function which is only available with cfg(test)
|
||||
// NB see the slice::hack module in slice.rs for more information
|
||||
#[cfg(test)]
|
||||
macro_rules! vec {
|
||||
($elem:expr; $n:expr) => (
|
||||
$crate::vec::from_elem($elem, $n)
|
||||
);
|
||||
($($x:expr),*) => (
|
||||
$crate::slice::into_vec(box [$($x),*])
|
||||
);
|
||||
($($x:expr,)*) => (vec![$($x),*])
|
||||
}
|
||||
|
||||
/// Use the syntax described in `std::fmt` to create a value of type `String`.
|
||||
/// See [`std::fmt`][fmt] for more information.
|
||||
///
|
||||
/// [fmt]: ../std/fmt/index.html
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// `format!` panics if a formatting trait implementation returns an error.
|
||||
/// This indicates an incorrect implementation
|
||||
/// since `fmt::Write for String` never returns an error itself.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// format!("test");
|
||||
/// format!("hello {}", "world!");
|
||||
/// format!("x = {}, y = {y}", 10, y = 30);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
macro_rules! format {
|
||||
($($arg:tt)*) => ($crate::fmt::format(format_args!($($arg)*)))
|
||||
}
|
||||
@@ -1,1997 +0,0 @@
|
||||
// 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.
|
||||
|
||||
//! Unicode string slices.
|
||||
//!
|
||||
//! The `&str` type is one of the two main string types, the other being `String`.
|
||||
//! Unlike its `String` counterpart, its contents are borrowed.
|
||||
//!
|
||||
//! # Basic Usage
|
||||
//!
|
||||
//! A basic string declaration of `&str` type:
|
||||
//!
|
||||
//! ```
|
||||
//! let hello_world = "Hello, World!";
|
||||
//! ```
|
||||
//!
|
||||
//! Here we have declared a string literal, also known as a string slice.
|
||||
//! String literals have a static lifetime, which means the string `hello_world`
|
||||
//! is guaranteed to be valid for the duration of the entire program.
|
||||
//! We can explicitly specify `hello_world`'s lifetime as well:
|
||||
//!
|
||||
//! ```
|
||||
//! let hello_world: &'static str = "Hello, world!";
|
||||
//! ```
|
||||
//!
|
||||
//! *[See also the `str` primitive type](../../std/primitive.str.html).*
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
// Many of the usings in this module are only used in the test configuration.
|
||||
// It's cleaner to just turn off the unused_imports warning than to fix them.
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use core::fmt;
|
||||
use core::str as core_str;
|
||||
use core::str::pattern::Pattern;
|
||||
use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
|
||||
use core::mem;
|
||||
use core::iter::FusedIterator;
|
||||
use std_unicode::str::{UnicodeStr, Utf16Encoder};
|
||||
|
||||
use vec_deque::VecDeque;
|
||||
use borrow::{Borrow, ToOwned};
|
||||
use string::String;
|
||||
use std_unicode;
|
||||
use vec::Vec;
|
||||
use slice::{SliceConcatExt, SliceIndex};
|
||||
use boxed::Box;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{FromStr, Utf8Error};
|
||||
#[allow(deprecated)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{Lines, LinesAny};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{Split, RSplit};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{SplitN, RSplitN};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{SplitTerminator, RSplitTerminator};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{Matches, RMatches};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{MatchIndices, RMatchIndices};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{from_utf8, from_utf8_mut, Chars, CharIndices, Bytes};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::{from_utf8_unchecked, from_utf8_unchecked_mut, ParseBoolError};
|
||||
#[unstable(feature = "str_box_extras", issue = "41119")]
|
||||
pub use alloc::str::from_boxed_utf8_unchecked;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use std_unicode::str::SplitWhitespace;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::str::pattern;
|
||||
|
||||
|
||||
#[unstable(feature = "slice_concat_ext",
|
||||
reason = "trait should not have to exist",
|
||||
issue = "27747")]
|
||||
impl<S: Borrow<str>> SliceConcatExt<str> for [S] {
|
||||
type Output = String;
|
||||
|
||||
fn concat(&self) -> String {
|
||||
if self.is_empty() {
|
||||
return String::new();
|
||||
}
|
||||
|
||||
// `len` calculation may overflow but push_str will check boundaries
|
||||
let len = self.iter().map(|s| s.borrow().len()).sum();
|
||||
let mut result = String::with_capacity(len);
|
||||
|
||||
for s in self {
|
||||
result.push_str(s.borrow())
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn join(&self, sep: &str) -> String {
|
||||
if self.is_empty() {
|
||||
return String::new();
|
||||
}
|
||||
|
||||
// concat is faster
|
||||
if sep.is_empty() {
|
||||
return self.concat();
|
||||
}
|
||||
|
||||
// this is wrong without the guarantee that `self` is non-empty
|
||||
// `len` calculation may overflow but push_str but will check boundaries
|
||||
let len = sep.len() * (self.len() - 1) +
|
||||
self.iter().map(|s| s.borrow().len()).sum::<usize>();
|
||||
let mut result = String::with_capacity(len);
|
||||
let mut first = true;
|
||||
|
||||
for s in self {
|
||||
if first {
|
||||
first = false;
|
||||
} else {
|
||||
result.push_str(sep);
|
||||
}
|
||||
result.push_str(s.borrow());
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn connect(&self, sep: &str) -> String {
|
||||
self.join(sep)
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator of [`u16`] over the string encoded as UTF-16.
|
||||
///
|
||||
/// [`u16`]: ../../std/primitive.u16.html
|
||||
///
|
||||
/// This struct is created by the [`encode_utf16`] method on [`str`].
|
||||
/// See its documentation for more.
|
||||
///
|
||||
/// [`encode_utf16`]: ../../std/primitive.str.html#method.encode_utf16
|
||||
/// [`str`]: ../../std/primitive.str.html
|
||||
#[derive(Clone)]
|
||||
#[stable(feature = "encode_utf16", since = "1.8.0")]
|
||||
pub struct EncodeUtf16<'a> {
|
||||
encoder: Utf16Encoder<Chars<'a>>,
|
||||
}
|
||||
|
||||
#[stable(feature = "collection_debug", since = "1.17.0")]
|
||||
impl<'a> fmt::Debug for EncodeUtf16<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.pad("EncodeUtf16 { .. }")
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "encode_utf16", since = "1.8.0")]
|
||||
impl<'a> Iterator for EncodeUtf16<'a> {
|
||||
type Item = u16;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<u16> {
|
||||
self.encoder.next()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.encoder.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "fused", issue = "35602")]
|
||||
impl<'a> FusedIterator for EncodeUtf16<'a> {}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Borrow<str> for String {
|
||||
#[inline]
|
||||
fn borrow(&self) -> &str {
|
||||
&self[..]
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl ToOwned for str {
|
||||
type Owned = String;
|
||||
fn to_owned(&self) -> String {
|
||||
unsafe { String::from_utf8_unchecked(self.as_bytes().to_owned()) }
|
||||
}
|
||||
|
||||
fn clone_into(&self, target: &mut String) {
|
||||
let mut b = mem::replace(target, String::new()).into_bytes();
|
||||
self.as_bytes().clone_into(&mut b);
|
||||
*target = unsafe { String::from_utf8_unchecked(b) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Methods for string slices.
|
||||
#[lang = "str"]
|
||||
#[cfg(not(test))]
|
||||
impl str {
|
||||
/// Returns the length of `self`.
|
||||
///
|
||||
/// This length is in bytes, not [`char`]s or graphemes. In other words,
|
||||
/// it may not be what a human considers the length of the string.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let len = "foo".len();
|
||||
/// assert_eq!(3, len);
|
||||
///
|
||||
/// let len = "ƒoo".len(); // fancy f!
|
||||
/// assert_eq!(4, len);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
core_str::StrExt::len(self)
|
||||
}
|
||||
|
||||
/// Returns `true` if `self` has a length of zero bytes.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "";
|
||||
/// assert!(s.is_empty());
|
||||
///
|
||||
/// let s = "not empty";
|
||||
/// assert!(!s.is_empty());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
core_str::StrExt::is_empty(self)
|
||||
}
|
||||
|
||||
/// Checks that `index`-th byte lies at the start and/or end of a
|
||||
/// UTF-8 code point sequence.
|
||||
///
|
||||
/// The start and end of the string (when `index == self.len()`) are
|
||||
/// considered to be
|
||||
/// boundaries.
|
||||
///
|
||||
/// Returns `false` if `index` is greater than `self.len()`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
/// assert!(s.is_char_boundary(0));
|
||||
/// // start of `老`
|
||||
/// assert!(s.is_char_boundary(6));
|
||||
/// assert!(s.is_char_boundary(s.len()));
|
||||
///
|
||||
/// // second byte of `ö`
|
||||
/// assert!(!s.is_char_boundary(2));
|
||||
///
|
||||
/// // third byte of `老`
|
||||
/// assert!(!s.is_char_boundary(8));
|
||||
/// ```
|
||||
#[stable(feature = "is_char_boundary", since = "1.9.0")]
|
||||
#[inline]
|
||||
pub fn is_char_boundary(&self, index: usize) -> bool {
|
||||
core_str::StrExt::is_char_boundary(self, index)
|
||||
}
|
||||
|
||||
/// Converts a string slice to a byte slice.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let bytes = "bors".as_bytes();
|
||||
/// assert_eq!(b"bors", bytes);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline(always)]
|
||||
pub fn as_bytes(&self) -> &[u8] {
|
||||
core_str::StrExt::as_bytes(self)
|
||||
}
|
||||
|
||||
/// Converts a mutable string slice to a mutable byte slice.
|
||||
#[unstable(feature = "str_mut_extras", issue = "41119")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
|
||||
core_str::StrExt::as_bytes_mut(self)
|
||||
}
|
||||
|
||||
/// Converts a string slice to a raw pointer.
|
||||
///
|
||||
/// As string slices are a slice of bytes, the raw pointer points to a
|
||||
/// [`u8`]. This pointer will be pointing to the first byte of the string
|
||||
/// slice.
|
||||
///
|
||||
/// [`u8`]: primitive.u8.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Hello";
|
||||
/// let ptr = s.as_ptr();
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn as_ptr(&self) -> *const u8 {
|
||||
core_str::StrExt::as_ptr(self)
|
||||
}
|
||||
|
||||
/// Returns a subslice of `str`.
|
||||
///
|
||||
/// This is the non-panicking alternative to indexing the `str`. Returns
|
||||
/// [`None`] whenever equivalent indexing operation would panic.
|
||||
///
|
||||
/// [`None`]: option/enum.Option.html#variant.None
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(str_checked_slicing)]
|
||||
/// let v = "🗻∈🌏";
|
||||
/// assert_eq!(Some("🗻"), v.get(0..4));
|
||||
/// assert!(v.get(1..).is_none());
|
||||
/// assert!(v.get(..8).is_none());
|
||||
/// assert!(v.get(..42).is_none());
|
||||
/// ```
|
||||
#[unstable(feature = "str_checked_slicing", issue = "39932")]
|
||||
#[inline]
|
||||
pub fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
|
||||
core_str::StrExt::get(self, i)
|
||||
}
|
||||
|
||||
/// Returns a mutable subslice of `str`.
|
||||
///
|
||||
/// This is the non-panicking alternative to indexing the `str`. Returns
|
||||
/// [`None`] whenever equivalent indexing operation would panic.
|
||||
///
|
||||
/// [`None`]: option/enum.Option.html#variant.None
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(str_checked_slicing)]
|
||||
/// let mut v = String::from("🗻∈🌏");
|
||||
/// assert_eq!(Some("🗻"), v.get_mut(0..4).map(|v| &*v));
|
||||
/// assert!(v.get_mut(1..).is_none());
|
||||
/// assert!(v.get_mut(..8).is_none());
|
||||
/// assert!(v.get_mut(..42).is_none());
|
||||
/// ```
|
||||
#[unstable(feature = "str_checked_slicing", issue = "39932")]
|
||||
#[inline]
|
||||
pub fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
|
||||
core_str::StrExt::get_mut(self, i)
|
||||
}
|
||||
|
||||
/// Returns a unchecked subslice of `str`.
|
||||
///
|
||||
/// This is the unchecked alternative to indexing the `str`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Callers of this function are responsible that these preconditions are
|
||||
/// satisfied:
|
||||
///
|
||||
/// * The starting index must come before the ending index;
|
||||
/// * Indexes must be within bounds of the original slice;
|
||||
/// * Indexes must lie on UTF-8 sequence boundaries.
|
||||
///
|
||||
/// Failing that, the returned string slice may reference invalid memory or
|
||||
/// violate the invariants communicated by the `str` type.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(str_checked_slicing)]
|
||||
/// let v = "🗻∈🌏";
|
||||
/// unsafe {
|
||||
/// assert_eq!("🗻", v.get_unchecked(0..4));
|
||||
/// assert_eq!("∈", v.get_unchecked(4..7));
|
||||
/// assert_eq!("🌏", v.get_unchecked(7..11));
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "str_checked_slicing", issue = "39932")]
|
||||
#[inline]
|
||||
pub unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output {
|
||||
core_str::StrExt::get_unchecked(self, i)
|
||||
}
|
||||
|
||||
/// Returns a mutable, unchecked subslice of `str`.
|
||||
///
|
||||
/// This is the unchecked alternative to indexing the `str`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Callers of this function are responsible that these preconditions are
|
||||
/// satisfied:
|
||||
///
|
||||
/// * The starting index must come before the ending index;
|
||||
/// * Indexes must be within bounds of the original slice;
|
||||
/// * Indexes must lie on UTF-8 sequence boundaries.
|
||||
///
|
||||
/// Failing that, the returned string slice may reference invalid memory or
|
||||
/// violate the invariants communicated by the `str` type.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(str_checked_slicing)]
|
||||
/// let mut v = String::from("🗻∈🌏");
|
||||
/// unsafe {
|
||||
/// assert_eq!("🗻", v.get_unchecked_mut(0..4));
|
||||
/// assert_eq!("∈", v.get_unchecked_mut(4..7));
|
||||
/// assert_eq!("🌏", v.get_unchecked_mut(7..11));
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "str_checked_slicing", issue = "39932")]
|
||||
#[inline]
|
||||
pub unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output {
|
||||
core_str::StrExt::get_unchecked_mut(self, i)
|
||||
}
|
||||
|
||||
/// Creates a string slice from another string slice, bypassing safety
|
||||
/// checks.
|
||||
///
|
||||
/// This is generally not recommended, use with caution! For a safe
|
||||
/// alternative see [`str`] and [`Index`].
|
||||
///
|
||||
/// [`str`]: primitive.str.html
|
||||
/// [`Index`]: ops/trait.Index.html
|
||||
///
|
||||
/// This new slice goes from `begin` to `end`, including `begin` but
|
||||
/// excluding `end`.
|
||||
///
|
||||
/// To get a mutable string slice instead, see the
|
||||
/// [`slice_mut_unchecked`] method.
|
||||
///
|
||||
/// [`slice_mut_unchecked`]: #method.slice_mut_unchecked
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Callers of this function are responsible that three preconditions are
|
||||
/// satisfied:
|
||||
///
|
||||
/// * `begin` must come before `end`.
|
||||
/// * `begin` and `end` must be byte positions within the string slice.
|
||||
/// * `begin` and `end` must lie on UTF-8 sequence boundaries.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
///
|
||||
/// unsafe {
|
||||
/// assert_eq!("Löwe 老虎 Léopard", s.slice_unchecked(0, 21));
|
||||
/// }
|
||||
///
|
||||
/// let s = "Hello, world!";
|
||||
///
|
||||
/// unsafe {
|
||||
/// assert_eq!("world", s.slice_unchecked(7, 12));
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
|
||||
core_str::StrExt::slice_unchecked(self, begin, end)
|
||||
}
|
||||
|
||||
/// Creates a string slice from another string slice, bypassing safety
|
||||
/// checks.
|
||||
/// This is generally not recommended, use with caution! For a safe
|
||||
/// alternative see [`str`] and [`IndexMut`].
|
||||
///
|
||||
/// [`str`]: primitive.str.html
|
||||
/// [`IndexMut`]: ops/trait.IndexMut.html
|
||||
///
|
||||
/// This new slice goes from `begin` to `end`, including `begin` but
|
||||
/// excluding `end`.
|
||||
///
|
||||
/// To get an immutable string slice instead, see the
|
||||
/// [`slice_unchecked`] method.
|
||||
///
|
||||
/// [`slice_unchecked`]: #method.slice_unchecked
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Callers of this function are responsible that three preconditions are
|
||||
/// satisfied:
|
||||
///
|
||||
/// * `begin` must come before `end`.
|
||||
/// * `begin` and `end` must be byte positions within the string slice.
|
||||
/// * `begin` and `end` must lie on UTF-8 sequence boundaries.
|
||||
#[stable(feature = "str_slice_mut", since = "1.5.0")]
|
||||
#[inline]
|
||||
pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str {
|
||||
core_str::StrExt::slice_mut_unchecked(self, begin, end)
|
||||
}
|
||||
|
||||
/// Divide one string slice into two at an index.
|
||||
///
|
||||
/// The argument, `mid`, should be a byte offset from the start of the
|
||||
/// string. It must also be on the boundary of a UTF-8 code point.
|
||||
///
|
||||
/// The two slices returned go from the start of the string slice to `mid`,
|
||||
/// and from `mid` to the end of the string slice.
|
||||
///
|
||||
/// To get mutable string slices instead, see the [`split_at_mut`]
|
||||
/// method.
|
||||
///
|
||||
/// [`split_at_mut`]: #method.split_at_mut
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `mid` is not on a UTF-8 code point boundary, or if it is
|
||||
/// beyond the last code point of the string slice.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Per Martin-Löf";
|
||||
///
|
||||
/// let (first, last) = s.split_at(3);
|
||||
///
|
||||
/// assert_eq!("Per", first);
|
||||
/// assert_eq!(" Martin-Löf", last);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "str_split_at", since = "1.4.0")]
|
||||
pub fn split_at(&self, mid: usize) -> (&str, &str) {
|
||||
core_str::StrExt::split_at(self, mid)
|
||||
}
|
||||
|
||||
/// Divide one mutable string slice into two at an index.
|
||||
///
|
||||
/// The argument, `mid`, should be a byte offset from the start of the
|
||||
/// string. It must also be on the boundary of a UTF-8 code point.
|
||||
///
|
||||
/// The two slices returned go from the start of the string slice to `mid`,
|
||||
/// and from `mid` to the end of the string slice.
|
||||
///
|
||||
/// To get immutable string slices instead, see the [`split_at`] method.
|
||||
///
|
||||
/// [`split_at`]: #method.split_at
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `mid` is not on a UTF-8 code point boundary, or if it is
|
||||
/// beyond the last code point of the string slice.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let mut s = "Per Martin-Löf".to_string();
|
||||
///
|
||||
/// let (first, last) = s.split_at_mut(3);
|
||||
///
|
||||
/// assert_eq!("Per", first);
|
||||
/// assert_eq!(" Martin-Löf", last);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "str_split_at", since = "1.4.0")]
|
||||
pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
|
||||
core_str::StrExt::split_at_mut(self, mid)
|
||||
}
|
||||
|
||||
/// Returns an iterator over the [`char`]s of a string slice.
|
||||
///
|
||||
/// As a string slice consists of valid UTF-8, we can iterate through a
|
||||
/// string slice by [`char`]. This method returns such an iterator.
|
||||
///
|
||||
/// It's important to remember that [`char`] represents a Unicode Scalar
|
||||
/// Value, and may not match your idea of what a 'character' is. Iteration
|
||||
/// over grapheme clusters may be what you actually want.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let word = "goodbye";
|
||||
///
|
||||
/// let count = word.chars().count();
|
||||
/// assert_eq!(7, count);
|
||||
///
|
||||
/// let mut chars = word.chars();
|
||||
///
|
||||
/// assert_eq!(Some('g'), chars.next());
|
||||
/// assert_eq!(Some('o'), chars.next());
|
||||
/// assert_eq!(Some('o'), chars.next());
|
||||
/// assert_eq!(Some('d'), chars.next());
|
||||
/// assert_eq!(Some('b'), chars.next());
|
||||
/// assert_eq!(Some('y'), chars.next());
|
||||
/// assert_eq!(Some('e'), chars.next());
|
||||
///
|
||||
/// assert_eq!(None, chars.next());
|
||||
/// ```
|
||||
///
|
||||
/// Remember, [`char`]s may not match your human intuition about characters:
|
||||
///
|
||||
/// ```
|
||||
/// let y = "y̆";
|
||||
///
|
||||
/// let mut chars = y.chars();
|
||||
///
|
||||
/// assert_eq!(Some('y'), chars.next()); // not 'y̆'
|
||||
/// assert_eq!(Some('\u{0306}'), chars.next());
|
||||
///
|
||||
/// assert_eq!(None, chars.next());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn chars(&self) -> Chars {
|
||||
core_str::StrExt::chars(self)
|
||||
}
|
||||
/// Returns an iterator over the [`char`]s of a string slice, and their
|
||||
/// positions.
|
||||
///
|
||||
/// As a string slice consists of valid UTF-8, we can iterate through a
|
||||
/// string slice by [`char`]. This method returns an iterator of both
|
||||
/// these [`char`]s, as well as their byte positions.
|
||||
///
|
||||
/// The iterator yields tuples. The position is first, the [`char`] is
|
||||
/// second.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let word = "goodbye";
|
||||
///
|
||||
/// let count = word.char_indices().count();
|
||||
/// assert_eq!(7, count);
|
||||
///
|
||||
/// let mut char_indices = word.char_indices();
|
||||
///
|
||||
/// assert_eq!(Some((0, 'g')), char_indices.next());
|
||||
/// assert_eq!(Some((1, 'o')), char_indices.next());
|
||||
/// assert_eq!(Some((2, 'o')), char_indices.next());
|
||||
/// assert_eq!(Some((3, 'd')), char_indices.next());
|
||||
/// assert_eq!(Some((4, 'b')), char_indices.next());
|
||||
/// assert_eq!(Some((5, 'y')), char_indices.next());
|
||||
/// assert_eq!(Some((6, 'e')), char_indices.next());
|
||||
///
|
||||
/// assert_eq!(None, char_indices.next());
|
||||
/// ```
|
||||
///
|
||||
/// Remember, [`char`]s may not match your human intuition about characters:
|
||||
///
|
||||
/// ```
|
||||
/// let y = "y̆";
|
||||
///
|
||||
/// let mut char_indices = y.char_indices();
|
||||
///
|
||||
/// assert_eq!(Some((0, 'y')), char_indices.next()); // not (0, 'y̆')
|
||||
/// assert_eq!(Some((1, '\u{0306}')), char_indices.next());
|
||||
///
|
||||
/// assert_eq!(None, char_indices.next());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn char_indices(&self) -> CharIndices {
|
||||
core_str::StrExt::char_indices(self)
|
||||
}
|
||||
|
||||
/// An iterator over the bytes of a string slice.
|
||||
///
|
||||
/// As a string slice consists of a sequence of bytes, we can iterate
|
||||
/// through a string slice by byte. This method returns such an iterator.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let mut bytes = "bors".bytes();
|
||||
///
|
||||
/// assert_eq!(Some(b'b'), bytes.next());
|
||||
/// assert_eq!(Some(b'o'), bytes.next());
|
||||
/// assert_eq!(Some(b'r'), bytes.next());
|
||||
/// assert_eq!(Some(b's'), bytes.next());
|
||||
///
|
||||
/// assert_eq!(None, bytes.next());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn bytes(&self) -> Bytes {
|
||||
core_str::StrExt::bytes(self)
|
||||
}
|
||||
|
||||
/// Split a string slice by whitespace.
|
||||
///
|
||||
/// The iterator returned will return string slices that are sub-slices of
|
||||
/// the original string slice, separated by any amount of whitespace.
|
||||
///
|
||||
/// 'Whitespace' is defined according to the terms of the Unicode Derived
|
||||
/// Core Property `White_Space`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let mut iter = "A few words".split_whitespace();
|
||||
///
|
||||
/// assert_eq!(Some("A"), iter.next());
|
||||
/// assert_eq!(Some("few"), iter.next());
|
||||
/// assert_eq!(Some("words"), iter.next());
|
||||
///
|
||||
/// assert_eq!(None, iter.next());
|
||||
/// ```
|
||||
///
|
||||
/// All kinds of whitespace are considered:
|
||||
///
|
||||
/// ```
|
||||
/// let mut iter = " Mary had\ta\u{2009}little \n\t lamb".split_whitespace();
|
||||
/// assert_eq!(Some("Mary"), iter.next());
|
||||
/// assert_eq!(Some("had"), iter.next());
|
||||
/// assert_eq!(Some("a"), iter.next());
|
||||
/// assert_eq!(Some("little"), iter.next());
|
||||
/// assert_eq!(Some("lamb"), iter.next());
|
||||
///
|
||||
/// assert_eq!(None, iter.next());
|
||||
/// ```
|
||||
#[stable(feature = "split_whitespace", since = "1.1.0")]
|
||||
#[inline]
|
||||
pub fn split_whitespace(&self) -> SplitWhitespace {
|
||||
UnicodeStr::split_whitespace(self)
|
||||
}
|
||||
|
||||
/// An iterator over the lines of a string, as string slices.
|
||||
///
|
||||
/// Lines are ended with either a newline (`\n`) or a carriage return with
|
||||
/// a line feed (`\r\n`).
|
||||
///
|
||||
/// The final line ending is optional.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let text = "foo\r\nbar\n\nbaz\n";
|
||||
/// let mut lines = text.lines();
|
||||
///
|
||||
/// assert_eq!(Some("foo"), lines.next());
|
||||
/// assert_eq!(Some("bar"), lines.next());
|
||||
/// assert_eq!(Some(""), lines.next());
|
||||
/// assert_eq!(Some("baz"), lines.next());
|
||||
///
|
||||
/// assert_eq!(None, lines.next());
|
||||
/// ```
|
||||
///
|
||||
/// The final line ending isn't required:
|
||||
///
|
||||
/// ```
|
||||
/// let text = "foo\nbar\n\r\nbaz";
|
||||
/// let mut lines = text.lines();
|
||||
///
|
||||
/// assert_eq!(Some("foo"), lines.next());
|
||||
/// assert_eq!(Some("bar"), lines.next());
|
||||
/// assert_eq!(Some(""), lines.next());
|
||||
/// assert_eq!(Some("baz"), lines.next());
|
||||
///
|
||||
/// assert_eq!(None, lines.next());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn lines(&self) -> Lines {
|
||||
core_str::StrExt::lines(self)
|
||||
}
|
||||
|
||||
/// An iterator over the lines of a string.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_deprecated(since = "1.4.0", reason = "use lines() instead now")]
|
||||
#[inline]
|
||||
#[allow(deprecated)]
|
||||
pub fn lines_any(&self) -> LinesAny {
|
||||
core_str::StrExt::lines_any(self)
|
||||
}
|
||||
|
||||
/// Returns an iterator of `u16` over the string encoded as UTF-16.
|
||||
#[stable(feature = "encode_utf16", since = "1.8.0")]
|
||||
pub fn encode_utf16(&self) -> EncodeUtf16 {
|
||||
EncodeUtf16 { encoder: Utf16Encoder::new(self[..].chars()) }
|
||||
}
|
||||
|
||||
/// Returns `true` if the given pattern matches a sub-slice of
|
||||
/// this string slice.
|
||||
///
|
||||
/// Returns `false` if it does not.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let bananas = "bananas";
|
||||
///
|
||||
/// assert!(bananas.contains("nana"));
|
||||
/// assert!(!bananas.contains("apples"));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
|
||||
core_str::StrExt::contains(self, pat)
|
||||
}
|
||||
|
||||
/// Returns `true` if the given pattern matches a prefix of this
|
||||
/// string slice.
|
||||
///
|
||||
/// Returns `false` if it does not.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let bananas = "bananas";
|
||||
///
|
||||
/// assert!(bananas.starts_with("bana"));
|
||||
/// assert!(!bananas.starts_with("nana"));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
|
||||
core_str::StrExt::starts_with(self, pat)
|
||||
}
|
||||
|
||||
/// Returns `true` if the given pattern matches a suffix of this
|
||||
/// string slice.
|
||||
///
|
||||
/// Returns `false` if it does not.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let bananas = "bananas";
|
||||
///
|
||||
/// assert!(bananas.ends_with("anas"));
|
||||
/// assert!(!bananas.ends_with("nana"));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::ends_with(self, pat)
|
||||
}
|
||||
|
||||
/// Returns the byte index of the first character of this string slice that
|
||||
/// matches the pattern.
|
||||
///
|
||||
/// Returns [`None`] if the pattern doesn't match.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines if
|
||||
/// a character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
/// [`None`]: option/enum.Option.html#variant.None
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Simple patterns:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
///
|
||||
/// assert_eq!(s.find('L'), Some(0));
|
||||
/// assert_eq!(s.find('é'), Some(14));
|
||||
/// assert_eq!(s.find("Léopard"), Some(13));
|
||||
/// ```
|
||||
///
|
||||
/// More complex patterns with closures:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
///
|
||||
/// assert_eq!(s.find(char::is_whitespace), Some(5));
|
||||
/// assert_eq!(s.find(char::is_lowercase), Some(1));
|
||||
/// ```
|
||||
///
|
||||
/// Not finding the pattern:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
/// let x: &[_] = &['1', '2'];
|
||||
///
|
||||
/// assert_eq!(s.find(x), None);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
|
||||
core_str::StrExt::find(self, pat)
|
||||
}
|
||||
|
||||
/// Returns the byte index of the last character of this string slice that
|
||||
/// matches the pattern.
|
||||
///
|
||||
/// Returns [`None`] if the pattern doesn't match.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines if
|
||||
/// a character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
/// [`None`]: option/enum.Option.html#variant.None
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Simple patterns:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
///
|
||||
/// assert_eq!(s.rfind('L'), Some(13));
|
||||
/// assert_eq!(s.rfind('é'), Some(14));
|
||||
/// ```
|
||||
///
|
||||
/// More complex patterns with closures:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
///
|
||||
/// assert_eq!(s.rfind(char::is_whitespace), Some(12));
|
||||
/// assert_eq!(s.rfind(char::is_lowercase), Some(20));
|
||||
/// ```
|
||||
///
|
||||
/// Not finding the pattern:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "Löwe 老虎 Léopard";
|
||||
/// let x: &[_] = &['1', '2'];
|
||||
///
|
||||
/// assert_eq!(s.rfind(x), None);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::rfind(self, pat)
|
||||
}
|
||||
|
||||
/// An iterator over substrings of this string slice, separated by
|
||||
/// characters matched by a pattern.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines the
|
||||
/// split.
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
|
||||
/// allows a reverse search and forward/reverse search yields the same
|
||||
/// elements. This is true for, eg, [`char`] but not for `&str`.
|
||||
///
|
||||
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
|
||||
///
|
||||
/// If the pattern allows a reverse search but its results might differ
|
||||
/// from a forward search, the [`rsplit`] method can be used.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
/// [`rsplit`]: #method.rsplit
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Simple patterns:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
|
||||
/// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "".split('X').collect();
|
||||
/// assert_eq!(v, [""]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect();
|
||||
/// assert_eq!(v, ["lion", "", "tiger", "leopard"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lion::tiger::leopard".split("::").collect();
|
||||
/// assert_eq!(v, ["lion", "tiger", "leopard"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "abc1def2ghi".split(char::is_numeric).collect();
|
||||
/// assert_eq!(v, ["abc", "def", "ghi"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lionXtigerXleopard".split(char::is_uppercase).collect();
|
||||
/// assert_eq!(v, ["lion", "tiger", "leopard"]);
|
||||
/// ```
|
||||
///
|
||||
/// A more complex pattern, using a closure:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "abc1defXghi".split(|c| c == '1' || c == 'X').collect();
|
||||
/// assert_eq!(v, ["abc", "def", "ghi"]);
|
||||
/// ```
|
||||
///
|
||||
/// If a string contains multiple contiguous separators, you will end up
|
||||
/// with empty strings in the output:
|
||||
///
|
||||
/// ```
|
||||
/// let x = "||||a||b|c".to_string();
|
||||
/// let d: Vec<_> = x.split('|').collect();
|
||||
///
|
||||
/// assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]);
|
||||
/// ```
|
||||
///
|
||||
/// Contiguous separators are separated by the empty string.
|
||||
///
|
||||
/// ```
|
||||
/// let x = "(///)".to_string();
|
||||
/// let d: Vec<_> = x.split('/').collect();
|
||||
///
|
||||
/// assert_eq!(d, &["(", "", "", ")"]);
|
||||
/// ```
|
||||
///
|
||||
/// Separators at the start or end of a string are neighbored
|
||||
/// by empty strings.
|
||||
///
|
||||
/// ```
|
||||
/// let d: Vec<_> = "010".split("0").collect();
|
||||
/// assert_eq!(d, &["", "1", ""]);
|
||||
/// ```
|
||||
///
|
||||
/// When the empty string is used as a separator, it separates
|
||||
/// every character in the string, along with the beginning
|
||||
/// and end of the string.
|
||||
///
|
||||
/// ```
|
||||
/// let f: Vec<_> = "rust".split("").collect();
|
||||
/// assert_eq!(f, &["", "r", "u", "s", "t", ""]);
|
||||
/// ```
|
||||
///
|
||||
/// Contiguous separators can lead to possibly surprising behavior
|
||||
/// when whitespace is used as the separator. This code is correct:
|
||||
///
|
||||
/// ```
|
||||
/// let x = " a b c".to_string();
|
||||
/// let d: Vec<_> = x.split(' ').collect();
|
||||
///
|
||||
/// assert_eq!(d, &["", "", "", "", "a", "", "b", "c"]);
|
||||
/// ```
|
||||
///
|
||||
/// It does _not_ give you:
|
||||
///
|
||||
/// ```,ignore
|
||||
/// assert_eq!(d, &["a", "b", "c"]);
|
||||
/// ```
|
||||
///
|
||||
/// Use [`split_whitespace`] for this behavior.
|
||||
///
|
||||
/// [`split_whitespace`]: #method.split_whitespace
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
|
||||
core_str::StrExt::split(self, pat)
|
||||
}
|
||||
|
||||
/// An iterator over substrings of the given string slice, separated by
|
||||
/// characters matched by a pattern and yielded in reverse order.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines the
|
||||
/// split.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator requires that the pattern supports a reverse
|
||||
/// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse
|
||||
/// search yields the same elements.
|
||||
///
|
||||
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
|
||||
///
|
||||
/// For iterating from the front, the [`split`] method can be used.
|
||||
///
|
||||
/// [`split`]: #method.split
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Simple patterns:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "Mary had a little lamb".rsplit(' ').collect();
|
||||
/// assert_eq!(v, ["lamb", "little", "a", "had", "Mary"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "".rsplit('X').collect();
|
||||
/// assert_eq!(v, [""]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lionXXtigerXleopard".rsplit('X').collect();
|
||||
/// assert_eq!(v, ["leopard", "tiger", "", "lion"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lion::tiger::leopard".rsplit("::").collect();
|
||||
/// assert_eq!(v, ["leopard", "tiger", "lion"]);
|
||||
/// ```
|
||||
///
|
||||
/// A more complex pattern, using a closure:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "abc1defXghi".rsplit(|c| c == '1' || c == 'X').collect();
|
||||
/// assert_eq!(v, ["ghi", "def", "abc"]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::rsplit(self, pat)
|
||||
}
|
||||
|
||||
/// An iterator over substrings of the given string slice, separated by
|
||||
/// characters matched by a pattern.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines the
|
||||
/// split.
|
||||
///
|
||||
/// Equivalent to [`split`], except that the trailing substring
|
||||
/// is skipped if empty.
|
||||
///
|
||||
/// [`split`]: #method.split
|
||||
///
|
||||
/// This method can be used for string data that is _terminated_,
|
||||
/// rather than _separated_ by a pattern.
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
|
||||
/// allows a reverse search and forward/reverse search yields the same
|
||||
/// elements. This is true for, eg, [`char`] but not for `&str`.
|
||||
///
|
||||
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// If the pattern allows a reverse search but its results might differ
|
||||
/// from a forward search, the [`rsplit_terminator`] method can be used.
|
||||
///
|
||||
/// [`rsplit_terminator`]: #method.rsplit_terminator
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "A.B.".split_terminator('.').collect();
|
||||
/// assert_eq!(v, ["A", "B"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "A..B..".split_terminator(".").collect();
|
||||
/// assert_eq!(v, ["A", "", "B", ""]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> {
|
||||
core_str::StrExt::split_terminator(self, pat)
|
||||
}
|
||||
|
||||
/// An iterator over substrings of `self`, separated by characters
|
||||
/// matched by a pattern and yielded in reverse order.
|
||||
///
|
||||
/// The pattern can be a simple `&str`, [`char`], or a closure that
|
||||
/// determines the split.
|
||||
/// Additional libraries might provide more complex patterns like
|
||||
/// regular expressions.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// Equivalent to [`split`], except that the trailing substring is
|
||||
/// skipped if empty.
|
||||
///
|
||||
/// [`split`]: #method.split
|
||||
///
|
||||
/// This method can be used for string data that is _terminated_,
|
||||
/// rather than _separated_ by a pattern.
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator requires that the pattern supports a
|
||||
/// reverse search, and it will be double ended if a forward/reverse
|
||||
/// search yields the same elements.
|
||||
///
|
||||
/// For iterating from the front, the [`split_terminator`] method can be
|
||||
/// used.
|
||||
///
|
||||
/// [`split_terminator`]: #method.split_terminator
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "A.B.".rsplit_terminator('.').collect();
|
||||
/// assert_eq!(v, ["B", "A"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "A..B..".rsplit_terminator(".").collect();
|
||||
/// assert_eq!(v, ["", "B", "", "A"]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::rsplit_terminator(self, pat)
|
||||
}
|
||||
|
||||
/// An iterator over substrings of the given string slice, separated by a
|
||||
/// pattern, restricted to returning at most `n` items.
|
||||
///
|
||||
/// If `n` substrings are returned, the last substring (the `n`th substring)
|
||||
/// will contain the remainder of the string.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines the
|
||||
/// split.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator will not be double ended, because it is
|
||||
/// not efficient to support.
|
||||
///
|
||||
/// If the pattern allows a reverse search, the [`rsplitn`] method can be
|
||||
/// used.
|
||||
///
|
||||
/// [`rsplitn`]: #method.rsplitn
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Simple patterns:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "Mary had a little lambda".splitn(3, ' ').collect();
|
||||
/// assert_eq!(v, ["Mary", "had", "a little lambda"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lionXXtigerXleopard".splitn(3, "X").collect();
|
||||
/// assert_eq!(v, ["lion", "", "tigerXleopard"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "abcXdef".splitn(1, 'X').collect();
|
||||
/// assert_eq!(v, ["abcXdef"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "".splitn(1, 'X').collect();
|
||||
/// assert_eq!(v, [""]);
|
||||
/// ```
|
||||
///
|
||||
/// A more complex pattern, using a closure:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "abc1defXghi".splitn(2, |c| c == '1' || c == 'X').collect();
|
||||
/// assert_eq!(v, ["abc", "defXghi"]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn splitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> SplitN<'a, P> {
|
||||
core_str::StrExt::splitn(self, n, pat)
|
||||
}
|
||||
|
||||
/// An iterator over substrings of this string slice, separated by a
|
||||
/// pattern, starting from the end of the string, restricted to returning
|
||||
/// at most `n` items.
|
||||
///
|
||||
/// If `n` substrings are returned, the last substring (the `n`th substring)
|
||||
/// will contain the remainder of the string.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that
|
||||
/// determines the split.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator will not be double ended, because it is not
|
||||
/// efficient to support.
|
||||
///
|
||||
/// For splitting from the front, the [`splitn`] method can be used.
|
||||
///
|
||||
/// [`splitn`]: #method.splitn
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Simple patterns:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "Mary had a little lamb".rsplitn(3, ' ').collect();
|
||||
/// assert_eq!(v, ["lamb", "little", "Mary had a"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(3, 'X').collect();
|
||||
/// assert_eq!(v, ["leopard", "tiger", "lionX"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lion::tiger::leopard".rsplitn(2, "::").collect();
|
||||
/// assert_eq!(v, ["leopard", "lion::tiger"]);
|
||||
/// ```
|
||||
///
|
||||
/// A more complex pattern, using a closure:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "abc1defXghi".rsplitn(2, |c| c == '1' || c == 'X').collect();
|
||||
/// assert_eq!(v, ["ghi", "abc1def"]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> RSplitN<'a, P>
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::rsplitn(self, n, pat)
|
||||
}
|
||||
|
||||
/// An iterator over the disjoint matches of a pattern within the given string
|
||||
/// slice.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that
|
||||
/// determines if a character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
|
||||
/// allows a reverse search and forward/reverse search yields the same
|
||||
/// elements. This is true for, eg, [`char`] but not for `&str`.
|
||||
///
|
||||
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// If the pattern allows a reverse search but its results might differ
|
||||
/// from a forward search, the [`rmatches`] method can be used.
|
||||
///
|
||||
/// [`rmatches`]: #method.rmatches
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "abcXXXabcYYYabc".matches("abc").collect();
|
||||
/// assert_eq!(v, ["abc", "abc", "abc"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "1abc2abc3".matches(char::is_numeric).collect();
|
||||
/// assert_eq!(v, ["1", "2", "3"]);
|
||||
/// ```
|
||||
#[stable(feature = "str_matches", since = "1.2.0")]
|
||||
#[inline]
|
||||
pub fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> {
|
||||
core_str::StrExt::matches(self, pat)
|
||||
}
|
||||
|
||||
/// An iterator over the disjoint matches of a pattern within this string slice,
|
||||
/// yielded in reverse order.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines if
|
||||
/// a character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator requires that the pattern supports a reverse
|
||||
/// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse
|
||||
/// search yields the same elements.
|
||||
///
|
||||
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
|
||||
///
|
||||
/// For iterating from the front, the [`matches`] method can be used.
|
||||
///
|
||||
/// [`matches`]: #method.matches
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "abcXXXabcYYYabc".rmatches("abc").collect();
|
||||
/// assert_eq!(v, ["abc", "abc", "abc"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "1abc2abc3".rmatches(char::is_numeric).collect();
|
||||
/// assert_eq!(v, ["3", "2", "1"]);
|
||||
/// ```
|
||||
#[stable(feature = "str_matches", since = "1.2.0")]
|
||||
#[inline]
|
||||
pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::rmatches(self, pat)
|
||||
}
|
||||
|
||||
/// An iterator over the disjoint matches of a pattern within this string
|
||||
/// slice as well as the index that the match starts at.
|
||||
///
|
||||
/// For matches of `pat` within `self` that overlap, only the indices
|
||||
/// corresponding to the first match are returned.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines
|
||||
/// if a character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator will be a [`DoubleEndedIterator`] if the pattern
|
||||
/// allows a reverse search and forward/reverse search yields the same
|
||||
/// elements. This is true for, eg, [`char`] but not for `&str`.
|
||||
///
|
||||
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
|
||||
///
|
||||
/// If the pattern allows a reverse search but its results might differ
|
||||
/// from a forward search, the [`rmatch_indices`] method can be used.
|
||||
///
|
||||
/// [`rmatch_indices`]: #method.rmatch_indices
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<_> = "abcXXXabcYYYabc".match_indices("abc").collect();
|
||||
/// assert_eq!(v, [(0, "abc"), (6, "abc"), (12, "abc")]);
|
||||
///
|
||||
/// let v: Vec<_> = "1abcabc2".match_indices("abc").collect();
|
||||
/// assert_eq!(v, [(1, "abc"), (4, "abc")]);
|
||||
///
|
||||
/// let v: Vec<_> = "ababa".match_indices("aba").collect();
|
||||
/// assert_eq!(v, [(0, "aba")]); // only the first `aba`
|
||||
/// ```
|
||||
#[stable(feature = "str_match_indices", since = "1.5.0")]
|
||||
#[inline]
|
||||
pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
|
||||
core_str::StrExt::match_indices(self, pat)
|
||||
}
|
||||
|
||||
/// An iterator over the disjoint matches of a pattern within `self`,
|
||||
/// yielded in reverse order along with the index of the match.
|
||||
///
|
||||
/// For matches of `pat` within `self` that overlap, only the indices
|
||||
/// corresponding to the last match are returned.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines if a
|
||||
/// character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Iterator behavior
|
||||
///
|
||||
/// The returned iterator requires that the pattern supports a reverse
|
||||
/// search, and it will be a [`DoubleEndedIterator`] if a forward/reverse
|
||||
/// search yields the same elements.
|
||||
///
|
||||
/// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html
|
||||
///
|
||||
/// For iterating from the front, the [`match_indices`] method can be used.
|
||||
///
|
||||
/// [`match_indices`]: #method.match_indices
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<_> = "abcXXXabcYYYabc".rmatch_indices("abc").collect();
|
||||
/// assert_eq!(v, [(12, "abc"), (6, "abc"), (0, "abc")]);
|
||||
///
|
||||
/// let v: Vec<_> = "1abcabc2".rmatch_indices("abc").collect();
|
||||
/// assert_eq!(v, [(4, "abc"), (1, "abc")]);
|
||||
///
|
||||
/// let v: Vec<_> = "ababa".rmatch_indices("aba").collect();
|
||||
/// assert_eq!(v, [(2, "aba")]); // only the last `aba`
|
||||
/// ```
|
||||
#[stable(feature = "str_match_indices", since = "1.5.0")]
|
||||
#[inline]
|
||||
pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::rmatch_indices(self, pat)
|
||||
}
|
||||
|
||||
/// Returns a string slice with leading and trailing whitespace removed.
|
||||
///
|
||||
/// 'Whitespace' is defined according to the terms of the Unicode Derived
|
||||
/// Core Property `White_Space`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = " Hello\tworld\t";
|
||||
///
|
||||
/// assert_eq!("Hello\tworld", s.trim());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn trim(&self) -> &str {
|
||||
UnicodeStr::trim(self)
|
||||
}
|
||||
|
||||
/// Returns a string slice with leading whitespace removed.
|
||||
///
|
||||
/// 'Whitespace' is defined according to the terms of the Unicode Derived
|
||||
/// Core Property `White_Space`.
|
||||
///
|
||||
/// # Text directionality
|
||||
///
|
||||
/// A string is a sequence of bytes. 'Left' in this context means the first
|
||||
/// position of that byte string; for a language like Arabic or Hebrew
|
||||
/// which are 'right to left' rather than 'left to right', this will be
|
||||
/// the _right_ side, not the left.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = " Hello\tworld\t";
|
||||
///
|
||||
/// assert_eq!("Hello\tworld\t", s.trim_left());
|
||||
/// ```
|
||||
///
|
||||
/// Directionality:
|
||||
///
|
||||
/// ```
|
||||
/// let s = " English";
|
||||
/// assert!(Some('E') == s.trim_left().chars().next());
|
||||
///
|
||||
/// let s = " עברית";
|
||||
/// assert!(Some('ע') == s.trim_left().chars().next());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn trim_left(&self) -> &str {
|
||||
UnicodeStr::trim_left(self)
|
||||
}
|
||||
|
||||
/// Returns a string slice with trailing whitespace removed.
|
||||
///
|
||||
/// 'Whitespace' is defined according to the terms of the Unicode Derived
|
||||
/// Core Property `White_Space`.
|
||||
///
|
||||
/// # Text directionality
|
||||
///
|
||||
/// A string is a sequence of bytes. 'Right' in this context means the last
|
||||
/// position of that byte string; for a language like Arabic or Hebrew
|
||||
/// which are 'right to left' rather than 'left to right', this will be
|
||||
/// the _left_ side, not the right.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = " Hello\tworld\t";
|
||||
///
|
||||
/// assert_eq!(" Hello\tworld", s.trim_right());
|
||||
/// ```
|
||||
///
|
||||
/// Directionality:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "English ";
|
||||
/// assert!(Some('h') == s.trim_right().chars().rev().next());
|
||||
///
|
||||
/// let s = "עברית ";
|
||||
/// assert!(Some('ת') == s.trim_right().chars().rev().next());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn trim_right(&self) -> &str {
|
||||
UnicodeStr::trim_right(self)
|
||||
}
|
||||
|
||||
/// Returns a string slice with all prefixes and suffixes that match a
|
||||
/// pattern repeatedly removed.
|
||||
///
|
||||
/// The pattern can be a [`char`] or a closure that determines if a
|
||||
/// character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Simple patterns:
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
|
||||
/// assert_eq!("123foo1bar123".trim_matches(char::is_numeric), "foo1bar");
|
||||
///
|
||||
/// let x: &[_] = &['1', '2'];
|
||||
/// assert_eq!("12foo1bar12".trim_matches(x), "foo1bar");
|
||||
/// ```
|
||||
///
|
||||
/// A more complex pattern, using a closure:
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!("1foo1barXX".trim_matches(|c| c == '1' || c == 'X'), "foo1bar");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
|
||||
where P::Searcher: DoubleEndedSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::trim_matches(self, pat)
|
||||
}
|
||||
|
||||
/// Returns a string slice with all prefixes that match a pattern
|
||||
/// repeatedly removed.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that determines if
|
||||
/// a character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Text directionality
|
||||
///
|
||||
/// A string is a sequence of bytes. 'Left' in this context means the first
|
||||
/// position of that byte string; for a language like Arabic or Hebrew
|
||||
/// which are 'right to left' rather than 'left to right', this will be
|
||||
/// the _right_ side, not the left.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
|
||||
/// assert_eq!("123foo1bar123".trim_left_matches(char::is_numeric), "foo1bar123");
|
||||
///
|
||||
/// let x: &[_] = &['1', '2'];
|
||||
/// assert_eq!("12foo1bar12".trim_left_matches(x), "foo1bar12");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
|
||||
core_str::StrExt::trim_left_matches(self, pat)
|
||||
}
|
||||
|
||||
/// Returns a string slice with all suffixes that match a pattern
|
||||
/// repeatedly removed.
|
||||
///
|
||||
/// The pattern can be a `&str`, [`char`], or a closure that
|
||||
/// determines if a character matches.
|
||||
///
|
||||
/// [`char`]: primitive.char.html
|
||||
///
|
||||
/// # Text directionality
|
||||
///
|
||||
/// A string is a sequence of bytes. 'Right' in this context means the last
|
||||
/// position of that byte string; for a language like Arabic or Hebrew
|
||||
/// which are 'right to left' rather than 'left to right', this will be
|
||||
/// the _left_ side, not the right.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Simple patterns:
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
|
||||
/// assert_eq!("123foo1bar123".trim_right_matches(char::is_numeric), "123foo1bar");
|
||||
///
|
||||
/// let x: &[_] = &['1', '2'];
|
||||
/// assert_eq!("12foo1bar12".trim_right_matches(x), "12foo1bar");
|
||||
/// ```
|
||||
///
|
||||
/// A more complex pattern, using a closure:
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!("1fooX".trim_left_matches(|c| c == '1' || c == 'X'), "fooX");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::trim_right_matches(self, pat)
|
||||
}
|
||||
|
||||
/// Parses this string slice into another type.
|
||||
///
|
||||
/// Because `parse` is so general, it can cause problems with type
|
||||
/// inference. As such, `parse` is one of the few times you'll see
|
||||
/// the syntax affectionately known as the 'turbofish': `::<>`. This
|
||||
/// helps the inference algorithm understand specifically which type
|
||||
/// you're trying to parse into.
|
||||
///
|
||||
/// `parse` can parse any type that implements the [`FromStr`] trait.
|
||||
///
|
||||
/// [`FromStr`]: str/trait.FromStr.html
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Will return [`Err`] if it's not possible to parse this string slice into
|
||||
/// the desired type.
|
||||
///
|
||||
/// [`Err`]: str/trait.FromStr.html#associatedtype.Err
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Basic usage
|
||||
///
|
||||
/// ```
|
||||
/// let four: u32 = "4".parse().unwrap();
|
||||
///
|
||||
/// assert_eq!(4, four);
|
||||
/// ```
|
||||
///
|
||||
/// Using the 'turbofish' instead of annotating `four`:
|
||||
///
|
||||
/// ```
|
||||
/// let four = "4".parse::<u32>();
|
||||
///
|
||||
/// assert_eq!(Ok(4), four);
|
||||
/// ```
|
||||
///
|
||||
/// Failing to parse:
|
||||
///
|
||||
/// ```
|
||||
/// let nope = "j".parse::<u32>();
|
||||
///
|
||||
/// assert!(nope.is_err());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
|
||||
core_str::StrExt::parse(self)
|
||||
}
|
||||
|
||||
/// Converts a `Box<str>` into a `Box<[u8]>` without copying or allocating.
|
||||
#[unstable(feature = "str_box_extras", issue = "41119")]
|
||||
pub fn into_boxed_bytes(self: Box<str>) -> Box<[u8]> {
|
||||
self.into()
|
||||
}
|
||||
|
||||
/// Replaces all matches of a pattern with another string.
|
||||
///
|
||||
/// `replace` creates a new [`String`], and copies the data from this string slice into it.
|
||||
/// While doing so, it attempts to find matches of a pattern. If it finds any, it
|
||||
/// replaces them with the replacement string slice.
|
||||
///
|
||||
/// [`String`]: string/struct.String.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "this is old";
|
||||
///
|
||||
/// assert_eq!("this is new", s.replace("old", "new"));
|
||||
/// ```
|
||||
///
|
||||
/// When the pattern doesn't match:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "this is old";
|
||||
/// assert_eq!(s, s.replace("cookie monster", "little lamb"));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
pub fn replace<'a, P: Pattern<'a>>(&'a self, from: P, to: &str) -> String {
|
||||
let mut result = String::new();
|
||||
let mut last_end = 0;
|
||||
for (start, part) in self.match_indices(from) {
|
||||
result.push_str(unsafe { self.slice_unchecked(last_end, start) });
|
||||
result.push_str(to);
|
||||
last_end = start + part.len();
|
||||
}
|
||||
result.push_str(unsafe { self.slice_unchecked(last_end, self.len()) });
|
||||
result
|
||||
}
|
||||
|
||||
/// Replaces first N matches of a pattern with another string.
|
||||
///
|
||||
/// `replacen` creates a new [`String`], and copies the data from this string slice into it.
|
||||
/// While doing so, it attempts to find matches of a pattern. If it finds any, it
|
||||
/// replaces them with the replacement string slice at most `count` times.
|
||||
///
|
||||
/// [`String`]: string/struct.String.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "foo foo 123 foo";
|
||||
/// assert_eq!("new new 123 foo", s.replacen("foo", "new", 2));
|
||||
/// assert_eq!("faa fao 123 foo", s.replacen('o', "a", 3));
|
||||
/// assert_eq!("foo foo new23 foo", s.replacen(char::is_numeric, "new", 1));
|
||||
/// ```
|
||||
///
|
||||
/// When the pattern doesn't match:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "this is old";
|
||||
/// assert_eq!(s, s.replacen("cookie monster", "little lamb", 10));
|
||||
/// ```
|
||||
#[stable(feature = "str_replacen", since = "1.16.0")]
|
||||
pub fn replacen<'a, P: Pattern<'a>>(&'a self, pat: P, to: &str, count: usize) -> String {
|
||||
// Hope to reduce the times of re-allocation
|
||||
let mut result = String::with_capacity(32);
|
||||
let mut last_end = 0;
|
||||
for (start, part) in self.match_indices(pat).take(count) {
|
||||
result.push_str(unsafe { self.slice_unchecked(last_end, start) });
|
||||
result.push_str(to);
|
||||
last_end = start + part.len();
|
||||
}
|
||||
result.push_str(unsafe { self.slice_unchecked(last_end, self.len()) });
|
||||
result
|
||||
}
|
||||
|
||||
/// Returns the lowercase equivalent of this string slice, as a new [`String`].
|
||||
///
|
||||
/// 'Lowercase' is defined according to the terms of the Unicode Derived Core Property
|
||||
/// `Lowercase`.
|
||||
///
|
||||
/// Since some characters can expand into multiple characters when changing
|
||||
/// the case, this function returns a [`String`] instead of modifying the
|
||||
/// parameter in-place.
|
||||
///
|
||||
/// [`String`]: string/struct.String.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "HELLO";
|
||||
///
|
||||
/// assert_eq!("hello", s.to_lowercase());
|
||||
/// ```
|
||||
///
|
||||
/// A tricky example, with sigma:
|
||||
///
|
||||
/// ```
|
||||
/// let sigma = "Σ";
|
||||
///
|
||||
/// assert_eq!("σ", sigma.to_lowercase());
|
||||
///
|
||||
/// // but at the end of a word, it's ς, not σ:
|
||||
/// let odysseus = "ὈΔΥΣΣΕΎΣ";
|
||||
///
|
||||
/// assert_eq!("ὀδυσσεύς", odysseus.to_lowercase());
|
||||
/// ```
|
||||
///
|
||||
/// Languages without case are not changed:
|
||||
///
|
||||
/// ```
|
||||
/// let new_year = "农历新年";
|
||||
///
|
||||
/// assert_eq!(new_year, new_year.to_lowercase());
|
||||
/// ```
|
||||
#[stable(feature = "unicode_case_mapping", since = "1.2.0")]
|
||||
pub fn to_lowercase(&self) -> String {
|
||||
let mut s = String::with_capacity(self.len());
|
||||
for (i, c) in self[..].char_indices() {
|
||||
if c == 'Σ' {
|
||||
// Σ maps to σ, except at the end of a word where it maps to ς.
|
||||
// This is the only conditional (contextual) but language-independent mapping
|
||||
// in `SpecialCasing.txt`,
|
||||
// so hard-code it rather than have a generic "condition" mechanism.
|
||||
// See https://github.com/rust-lang/rust/issues/26035
|
||||
map_uppercase_sigma(self, i, &mut s)
|
||||
} else {
|
||||
s.extend(c.to_lowercase());
|
||||
}
|
||||
}
|
||||
return s;
|
||||
|
||||
fn map_uppercase_sigma(from: &str, i: usize, to: &mut String) {
|
||||
// See http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992
|
||||
// for the definition of `Final_Sigma`.
|
||||
debug_assert!('Σ'.len_utf8() == 2);
|
||||
let is_word_final = case_ignoreable_then_cased(from[..i].chars().rev()) &&
|
||||
!case_ignoreable_then_cased(from[i + 2..].chars());
|
||||
to.push_str(if is_word_final { "ς" } else { "σ" });
|
||||
}
|
||||
|
||||
fn case_ignoreable_then_cased<I: Iterator<Item = char>>(iter: I) -> bool {
|
||||
use std_unicode::derived_property::{Cased, Case_Ignorable};
|
||||
match iter.skip_while(|&c| Case_Ignorable(c)).next() {
|
||||
Some(c) => Cased(c),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the uppercase equivalent of this string slice, as a new [`String`].
|
||||
///
|
||||
/// 'Uppercase' is defined according to the terms of the Unicode Derived Core Property
|
||||
/// `Uppercase`.
|
||||
///
|
||||
/// Since some characters can expand into multiple characters when changing
|
||||
/// the case, this function returns a [`String`] instead of modifying the
|
||||
/// parameter in-place.
|
||||
///
|
||||
/// [`String`]: string/struct.String.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let s = "hello";
|
||||
///
|
||||
/// assert_eq!("HELLO", s.to_uppercase());
|
||||
/// ```
|
||||
///
|
||||
/// Scripts without case are not changed:
|
||||
///
|
||||
/// ```
|
||||
/// let new_year = "农历新年";
|
||||
///
|
||||
/// assert_eq!(new_year, new_year.to_uppercase());
|
||||
/// ```
|
||||
#[stable(feature = "unicode_case_mapping", since = "1.2.0")]
|
||||
pub fn to_uppercase(&self) -> String {
|
||||
let mut s = String::with_capacity(self.len());
|
||||
s.extend(self.chars().flat_map(|c| c.to_uppercase()));
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Escapes each char in `s` with [`char::escape_debug`].
|
||||
///
|
||||
/// [`char::escape_debug`]: primitive.char.html#method.escape_debug
|
||||
#[unstable(feature = "str_escape",
|
||||
reason = "return type may change to be an iterator",
|
||||
issue = "27791")]
|
||||
pub fn escape_debug(&self) -> String {
|
||||
self.chars().flat_map(|c| c.escape_debug()).collect()
|
||||
}
|
||||
|
||||
/// Escapes each char in `s` with [`char::escape_default`].
|
||||
///
|
||||
/// [`char::escape_default`]: primitive.char.html#method.escape_default
|
||||
#[unstable(feature = "str_escape",
|
||||
reason = "return type may change to be an iterator",
|
||||
issue = "27791")]
|
||||
pub fn escape_default(&self) -> String {
|
||||
self.chars().flat_map(|c| c.escape_default()).collect()
|
||||
}
|
||||
|
||||
/// Escapes each char in `s` with [`char::escape_unicode`].
|
||||
///
|
||||
/// [`char::escape_unicode`]: primitive.char.html#method.escape_unicode
|
||||
#[unstable(feature = "str_escape",
|
||||
reason = "return type may change to be an iterator",
|
||||
issue = "27791")]
|
||||
pub fn escape_unicode(&self) -> String {
|
||||
self.chars().flat_map(|c| c.escape_unicode()).collect()
|
||||
}
|
||||
|
||||
/// Converts a [`Box<str>`] into a [`String`] without copying or allocating.
|
||||
///
|
||||
/// [`String`]: string/struct.String.html
|
||||
/// [`Box<str>`]: boxed/struct.Box.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// let string = String::from("birthday gift");
|
||||
/// let boxed_str = string.clone().into_boxed_str();
|
||||
///
|
||||
/// assert_eq!(boxed_str.into_string(), string);
|
||||
/// ```
|
||||
#[stable(feature = "box_str", since = "1.4.0")]
|
||||
pub fn into_string(self: Box<str>) -> String {
|
||||
unsafe {
|
||||
let slice = mem::transmute::<Box<str>, Box<[u8]>>(self);
|
||||
String::from_utf8_unchecked(slice.into_vec())
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a [`String`] by repeating a string `n` times.
|
||||
///
|
||||
/// [`String`]: string/struct.String.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// assert_eq!("abc".repeat(4), String::from("abcabcabcabc"));
|
||||
/// ```
|
||||
#[stable(feature = "repeat_str", since = "1.16.0")]
|
||||
pub fn repeat(&self, n: usize) -> String {
|
||||
let mut s = String::with_capacity(self.len() * n);
|
||||
s.extend((0..n).map(|_| self));
|
||||
s
|
||||
}
|
||||
}
|
||||
@@ -2015,7 +2015,7 @@ fn index_mut(self, slice: &mut str) -> &mut Self::Output {
|
||||
issue = "32110")]
|
||||
pub trait StrExt {
|
||||
// NB there are no docs here are they're all located on the StrExt trait in
|
||||
// libcollections, not here.
|
||||
// liballoc, not here.
|
||||
|
||||
#[stable(feature = "core", since = "1.6.0")]
|
||||
fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool;
|
||||
|
||||
@@ -26,7 +26,7 @@ pub fn FnvHashSet<V: Hash + Eq>() -> FnvHashSet<V> {
|
||||
}
|
||||
|
||||
/// A speedy hash algorithm for node ids and def ids. The hashmap in
|
||||
/// libcollections by default uses SipHash which isn't quite as speedy as we
|
||||
/// liballoc by default uses SipHash which isn't quite as speedy as we
|
||||
/// want. In the compiler we're not really worried about DOS attempts, so we
|
||||
/// just default to a non-cryptographic hash.
|
||||
///
|
||||
|
||||
@@ -26,7 +26,7 @@ pub fn FxHashSet<V: Hash + Eq>() -> FxHashSet<V> {
|
||||
HashSet::default()
|
||||
}
|
||||
|
||||
/// A speedy hash algorithm for use within rustc. The hashmap in libcollections
|
||||
/// A speedy hash algorithm for use within rustc. The hashmap in liballoc
|
||||
/// by default uses SipHash which isn't quite as speedy as we want. In the
|
||||
/// compiler we're not really worried about DOS attempts, so we use a fast
|
||||
/// non-cryptographic hash.
|
||||
|
||||
@@ -188,16 +188,16 @@ fn main() {}
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0254
|
||||
extern crate collections;
|
||||
extern crate alloc;
|
||||
|
||||
mod foo {
|
||||
pub trait collections {
|
||||
pub trait alloc {
|
||||
fn do_something();
|
||||
}
|
||||
}
|
||||
|
||||
use foo::collections; // error: an extern crate named `collections` has already
|
||||
// been imported in this module
|
||||
use foo::alloc; // error: an extern crate named `alloc` has already
|
||||
// been imported in this module
|
||||
|
||||
fn main() {}
|
||||
```
|
||||
@@ -206,15 +206,15 @@ fn main() {}
|
||||
Example:
|
||||
|
||||
```ignore
|
||||
extern crate collections as libcollections; // ok!
|
||||
extern crate alloc as liballoc; // ok!
|
||||
|
||||
mod foo {
|
||||
pub trait collections {
|
||||
pub trait alloc {
|
||||
fn do_something();
|
||||
}
|
||||
}
|
||||
|
||||
use foo::collections;
|
||||
use foo::alloc;
|
||||
|
||||
fn main() {}
|
||||
```
|
||||
@@ -1425,7 +1425,7 @@ mod foo {
|
||||
|
||||
```compile_fail,E0469
|
||||
#[macro_use(drink, be_merry)] // error: imported macro not found
|
||||
extern crate collections;
|
||||
extern crate alloc;
|
||||
|
||||
fn main() {
|
||||
// ...
|
||||
@@ -1467,7 +1467,7 @@ macro_rules! drink {
|
||||
|
||||
```compile_fail,E0470
|
||||
#[macro_reexport(drink, be_merry)]
|
||||
extern crate collections;
|
||||
extern crate alloc;
|
||||
|
||||
fn main() {
|
||||
// ...
|
||||
|
||||
@@ -2265,8 +2265,8 @@ fn make(&mut self) -> Foo<T> {
|
||||
following trait `impl` is an error:
|
||||
|
||||
```compile_fail,E0210
|
||||
extern crate collections;
|
||||
use collections::range::RangeArgument;
|
||||
extern crate alloc;
|
||||
use alloc::range::RangeArgument;
|
||||
|
||||
impl<T> RangeArgument<T> for T { } // error
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Implementations of serialization for structures found in libcollections
|
||||
//! Implementations of serialization for structures found in liballoc
|
||||
|
||||
use std::hash::{Hash, BuildHasher};
|
||||
|
||||
|
||||
@@ -28,15 +28,12 @@
|
||||
#![deny(warnings)]
|
||||
|
||||
#![feature(box_syntax)]
|
||||
#![feature(collections)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(i128_type)]
|
||||
#![feature(specialization)]
|
||||
#![cfg_attr(stage0, feature(staged_api))]
|
||||
#![cfg_attr(test, feature(test))]
|
||||
|
||||
extern crate collections;
|
||||
|
||||
pub use self::serialize::{Decoder, Encoder, Decodable, Encodable};
|
||||
|
||||
pub use self::serialize::{SpecializationError, SpecializedEncoder, SpecializedDecoder};
|
||||
|
||||
@@ -15,7 +15,6 @@ alloc_jemalloc = { path = "../liballoc_jemalloc", optional = true }
|
||||
alloc_system = { path = "../liballoc_system" }
|
||||
panic_unwind = { path = "../libpanic_unwind", optional = true }
|
||||
panic_abort = { path = "../libpanic_abort" }
|
||||
collections = { path = "../libcollections" }
|
||||
core = { path = "../libcore" }
|
||||
libc = { path = "../rustc/libc_shim" }
|
||||
rand = { path = "../librand" }
|
||||
|
||||
@@ -420,15 +420,15 @@
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core_collections::Bound;
|
||||
pub use alloc::Bound;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core_collections::{BinaryHeap, BTreeMap, BTreeSet};
|
||||
pub use alloc::{BinaryHeap, BTreeMap, BTreeSet};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core_collections::{LinkedList, VecDeque};
|
||||
pub use alloc::{LinkedList, VecDeque};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core_collections::{binary_heap, btree_map, btree_set};
|
||||
pub use alloc::{binary_heap, btree_map, btree_set};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core_collections::{linked_list, vec_deque};
|
||||
pub use alloc::{linked_list, vec_deque};
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use self::hash_map::HashMap;
|
||||
@@ -436,7 +436,7 @@
|
||||
pub use self::hash_set::HashSet;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core_collections::range;
|
||||
pub use alloc::range;
|
||||
|
||||
mod hash;
|
||||
|
||||
|
||||
+7
-10
@@ -254,7 +254,6 @@
|
||||
#![feature(cfg_target_vendor)]
|
||||
#![feature(char_escape_debug)]
|
||||
#![feature(char_internals)]
|
||||
#![feature(collections)]
|
||||
#![feature(collections_range)]
|
||||
#![feature(compiler_builtins_lib)]
|
||||
#![feature(const_fn)]
|
||||
@@ -337,11 +336,9 @@
|
||||
debug_assert_ne, unreachable, unimplemented, write, writeln, try)]
|
||||
extern crate core as __core;
|
||||
|
||||
#[allow(deprecated)] extern crate rand as core_rand;
|
||||
#[macro_use]
|
||||
#[macro_reexport(vec, format)]
|
||||
extern crate collections as core_collections;
|
||||
|
||||
#[allow(deprecated)] extern crate rand as core_rand;
|
||||
extern crate alloc;
|
||||
extern crate std_unicode;
|
||||
extern crate libc;
|
||||
@@ -430,17 +427,17 @@
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use alloc::rc;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core_collections::borrow;
|
||||
pub use alloc::borrow;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core_collections::fmt;
|
||||
pub use alloc::fmt;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core_collections::slice;
|
||||
pub use alloc::slice;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core_collections::str;
|
||||
pub use alloc::str;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core_collections::string;
|
||||
pub use alloc::string;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core_collections::vec;
|
||||
pub use alloc::vec;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use std_unicode::char;
|
||||
#[unstable(feature = "i128", issue = "35118")]
|
||||
|
||||
@@ -52,7 +52,7 @@ pub mod str {
|
||||
pub use u_str::Utf16Encoder;
|
||||
}
|
||||
|
||||
// For use in libcollections, not re-exported in libstd.
|
||||
// For use in liballoc, not re-exported in libstd.
|
||||
pub mod derived_property {
|
||||
pub use tables::derived_property::{Case_Ignorable, Cased};
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ pub struct SplitWhitespace<'a> {
|
||||
}
|
||||
|
||||
/// Methods for Unicode string slices
|
||||
#[allow(missing_docs)] // docs in libcollections
|
||||
#[allow(missing_docs)] // docs in liballoc
|
||||
pub trait UnicodeStr {
|
||||
fn split_whitespace<'a>(&'a self) -> SplitWhitespace<'a>;
|
||||
fn is_whitespace(&self) -> bool;
|
||||
|
||||
@@ -8,18 +8,18 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(collections)]
|
||||
#![feature(alloc)]
|
||||
|
||||
extern crate collections;
|
||||
//~^ NOTE previous import of `collections` here
|
||||
extern crate alloc;
|
||||
//~^ NOTE previous import of `alloc` here
|
||||
|
||||
mod foo {
|
||||
pub trait collections {
|
||||
pub trait alloc {
|
||||
fn do_something();
|
||||
}
|
||||
}
|
||||
|
||||
use foo::collections;
|
||||
use foo::alloc;
|
||||
//~^ ERROR E0254
|
||||
//~| NOTE already imported
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(collections, libc)]
|
||||
#![feature(alloc, libc)]
|
||||
|
||||
extern crate collections;
|
||||
//~^ NOTE previous import of `collections` here
|
||||
extern crate alloc;
|
||||
//~^ NOTE previous import of `alloc` here
|
||||
|
||||
extern crate libc as collections;
|
||||
extern crate libc as alloc;
|
||||
//~^ ERROR E0259
|
||||
//~| NOTE `collections` already imported
|
||||
//~| NOTE `alloc` already imported
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(collections)]
|
||||
#![feature(alloc)]
|
||||
|
||||
extern crate collections;
|
||||
//~^ NOTE previous import of `collections` here
|
||||
extern crate alloc;
|
||||
//~^ NOTE previous import of `alloc` here
|
||||
|
||||
mod collections {
|
||||
//~^ ERROR `collections` has already been imported in this module [E0260]
|
||||
//~| NOTE `collections` already imported
|
||||
mod alloc {
|
||||
//~^ ERROR `alloc` has already been imported in this module [E0260]
|
||||
//~| NOTE `alloc` already imported
|
||||
pub trait MyTrait {
|
||||
fn do_something();
|
||||
}
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
#![deny(unused_extern_crates)]
|
||||
#![allow(unused_variables)]
|
||||
#![allow(deprecated)]
|
||||
#![feature(alloc)]
|
||||
#![feature(libc)]
|
||||
#![feature(collections)]
|
||||
#![feature(rand)]
|
||||
|
||||
extern crate libc; //~ ERROR: unused extern crate
|
||||
|
||||
extern crate collections as collecs; // no error, it is used
|
||||
extern crate alloc as collecs; // no error, it is used
|
||||
|
||||
extern crate rand; // no error, the use marks it as used
|
||||
// even if imported objects aren't used
|
||||
|
||||
@@ -8,25 +8,25 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(collections)]
|
||||
#![feature(alloc)]
|
||||
|
||||
mod a {
|
||||
extern crate collections;
|
||||
use collections::HashMap;
|
||||
//~^ ERROR unresolved import `collections::HashMap` [E0432]
|
||||
//~| Did you mean `self::collections`?
|
||||
extern crate alloc;
|
||||
use alloc::HashMap;
|
||||
//~^ ERROR unresolved import `alloc::HashMap` [E0432]
|
||||
//~| Did you mean `self::alloc`?
|
||||
mod b {
|
||||
use collections::HashMap;
|
||||
//~^ ERROR unresolved import `collections::HashMap` [E0432]
|
||||
//~| Did you mean `a::collections`?
|
||||
use alloc::HashMap;
|
||||
//~^ ERROR unresolved import `alloc::HashMap` [E0432]
|
||||
//~| Did you mean `a::alloc`?
|
||||
mod c {
|
||||
use collections::HashMap;
|
||||
//~^ ERROR unresolved import `collections::HashMap` [E0432]
|
||||
//~| Did you mean `a::collections`?
|
||||
use alloc::HashMap;
|
||||
//~^ ERROR unresolved import `alloc::HashMap` [E0432]
|
||||
//~| Did you mean `a::alloc`?
|
||||
mod d {
|
||||
use collections::HashMap;
|
||||
//~^ ERROR unresolved import `collections::HashMap` [E0432]
|
||||
//~| Did you mean `a::collections`?
|
||||
use alloc::HashMap;
|
||||
//~^ ERROR unresolved import `alloc::HashMap` [E0432]
|
||||
//~| Did you mean `a::alloc`?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(collections)]
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate collections;
|
||||
extern crate serialize;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
@@ -15,10 +15,9 @@
|
||||
// - Multiple lifetime parameters
|
||||
// - Arenas
|
||||
|
||||
#![feature(rustc_private, libc, collections)]
|
||||
#![feature(rustc_private, libc)]
|
||||
|
||||
extern crate arena;
|
||||
extern crate collections;
|
||||
extern crate libc;
|
||||
|
||||
use TypeStructure::{TypeInt, TypeFunction};
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
#![feature(collections)]
|
||||
|
||||
fn main() {
|
||||
let args = vec!["foobie", "asdf::asdf"];
|
||||
let arr: Vec<&str> = args[1].split("::").collect();
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(lang_items, start, collections)]
|
||||
#![feature(lang_items, start, alloc)]
|
||||
#![no_std]
|
||||
|
||||
extern crate std as other;
|
||||
|
||||
#[macro_use] extern crate collections;
|
||||
#[macro_use] extern crate alloc;
|
||||
|
||||
#[start]
|
||||
fn start(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
|
||||
@@ -9,10 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
#![feature(collections)]
|
||||
|
||||
extern crate collections;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
// This is a fancy one: it uses an external iterator established
|
||||
|
||||
@@ -9,10 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
#![feature(collections)]
|
||||
|
||||
extern crate collections;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub fn main() {
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
|
||||
// ignore-emscripten missing rust_begin_unwind
|
||||
|
||||
#![feature(lang_items, start, collections)]
|
||||
#![feature(lang_items, start, alloc)]
|
||||
#![no_std]
|
||||
|
||||
extern crate std as other;
|
||||
|
||||
#[macro_use] extern crate collections;
|
||||
#[macro_use] extern crate alloc;
|
||||
|
||||
use collections::string::ToString;
|
||||
use alloc::string::ToString;
|
||||
|
||||
#[start]
|
||||
fn start(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
|
||||
@@ -8,10 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(collections)]
|
||||
|
||||
extern crate collections;
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
|
||||
@@ -8,10 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(collections)]
|
||||
|
||||
extern crate collections;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub fn main() {
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
#![feature(collections)]
|
||||
|
||||
fn main() {
|
||||
let mut escaped = String::from("");
|
||||
for c in '\u{10401}'.escape_unicode() {
|
||||
|
||||
@@ -10,9 +10,6 @@
|
||||
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
#![feature(collections)]
|
||||
|
||||
extern crate collections;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
pub fn main() {
|
||||
|
||||
@@ -11,10 +11,6 @@
|
||||
// Minimized version of issue-2804.rs. Both check that callee IDs don't
|
||||
// clobber the previous node ID in a macro expr
|
||||
|
||||
#![feature(collections)]
|
||||
|
||||
extern crate collections;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn add_interfaces(managed_ip: String, device: HashMap<String, isize>) {
|
||||
|
||||
@@ -10,10 +10,7 @@
|
||||
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
#![allow(unknown_features)]
|
||||
#![feature(box_syntax, collections)]
|
||||
|
||||
extern crate collections;
|
||||
#![feature(box_syntax)]
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
||||
@@ -8,10 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(collections)]
|
||||
|
||||
extern crate collections;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn check_strs(actual: &str, expected: &str) -> bool {
|
||||
|
||||
@@ -9,10 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
#![allow(unknown_features)]
|
||||
#![feature(box_syntax, collections)]
|
||||
|
||||
extern crate collections;
|
||||
#![feature(box_syntax)]
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
||||
@@ -13,10 +13,6 @@
|
||||
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
#![feature(collections)]
|
||||
|
||||
extern crate collections;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
struct A(isize, isize);
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(collections)]
|
||||
|
||||
use std::string::String;
|
||||
|
||||
fn test_stack_assign() {
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
#![feature(collections)]
|
||||
|
||||
pub fn main() {
|
||||
let s = "\u{2603}";
|
||||
assert_eq!(s, "☃");
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(collections)]
|
||||
|
||||
pub fn main() {
|
||||
let thing = "{{ f }}";
|
||||
let f = thing.find("{{");
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(unknown_features)]
|
||||
#![feature(box_syntax, collections, core)]
|
||||
#![feature(box_syntax, core)]
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(collections)]
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::string::String;
|
||||
|
||||
@@ -9,21 +9,16 @@
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(warnings)]
|
||||
#![feature(collections)]
|
||||
#![feature(drain, collections_bound, btree_range, vecmap)]
|
||||
|
||||
extern crate collections;
|
||||
|
||||
use collections::BinaryHeap;
|
||||
use collections::{BTreeMap, BTreeSet};
|
||||
use collections::LinkedList;
|
||||
use collections::String;
|
||||
use collections::Vec;
|
||||
use collections::VecDeque;
|
||||
use std::collections::BinaryHeap;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::collections::LinkedList;
|
||||
use std::collections::VecDeque;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
|
||||
use collections::Bound::Included;
|
||||
use std::collections::Bound::Included;
|
||||
use std::mem;
|
||||
|
||||
fn is_sync<T>(_: T) where T: Sync {}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
//
|
||||
|
||||
#![feature(collections, core, str_char)]
|
||||
#![feature(core, str_char)]
|
||||
|
||||
use std::str;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(lang_items, start, libc, collections)]
|
||||
#![feature(lang_items, start, libc, alloc)]
|
||||
#![no_std]
|
||||
|
||||
extern crate std as other;
|
||||
@@ -16,9 +16,9 @@
|
||||
extern crate libc;
|
||||
|
||||
#[macro_use]
|
||||
extern crate collections;
|
||||
extern crate alloc;
|
||||
|
||||
use collections::vec::Vec;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
// Issue #16806
|
||||
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(collections)]
|
||||
|
||||
use std::string::String;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
|
||||
@@ -118,15 +118,15 @@ fn check(cache: &mut Cache,
|
||||
return None;
|
||||
}
|
||||
// FIXME(#32553)
|
||||
if file.ends_with("collections/string/struct.String.html") {
|
||||
if file.ends_with("string/struct.String.html") {
|
||||
return None;
|
||||
}
|
||||
// FIXME(#32130)
|
||||
if file.ends_with("btree_set/struct.BTreeSet.html") ||
|
||||
file.ends_with("collections/struct.BTreeSet.html") ||
|
||||
file.ends_with("collections/btree_map/struct.BTreeMap.html") ||
|
||||
file.ends_with("collections/hash_map/struct.HashMap.html") ||
|
||||
file.ends_with("collections/hash_set/struct.HashSet.html") {
|
||||
file.ends_with("struct.BTreeSet.html") ||
|
||||
file.ends_with("btree_map/struct.BTreeMap.html") ||
|
||||
file.ends_with("hash_map/struct.HashMap.html") ||
|
||||
file.ends_with("hash_set/struct.HashSet.html") {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user