2014-04-02 16:54:22 -07:00
|
|
|
|
// Copyright 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.
|
|
|
|
|
|
2015-12-01 13:39:48 -05:00
|
|
|
|
//! A UTF-8 encoded, growable string.
|
|
|
|
|
//!
|
|
|
|
|
//! This module contains the [`String`] type, a trait for converting
|
|
|
|
|
//! [`ToString`]s, and several error types that may result from working with
|
|
|
|
|
//! [`String`]s.
|
|
|
|
|
//!
|
|
|
|
|
//! [`ToString`]: trait.ToString.html
|
2016-01-07 14:54:17 -05:00
|
|
|
|
//!
|
|
|
|
|
//! # Examples
|
|
|
|
|
//!
|
2016-10-10 18:15:55 +02:00
|
|
|
|
//! There are multiple ways to create a new [`String`] from a string literal:
|
2016-01-07 14:54:17 -05:00
|
|
|
|
//!
|
2016-09-21 17:07:45 +02:00
|
|
|
|
//! ```
|
2016-01-07 14:54:17 -05:00
|
|
|
|
//! let s = "Hello".to_string();
|
|
|
|
|
//!
|
|
|
|
|
//! let s = String::from("world");
|
|
|
|
|
//! let s: String = "also this".into();
|
|
|
|
|
//! ```
|
|
|
|
|
//!
|
2016-10-10 18:15:55 +02:00
|
|
|
|
//! You can create a new [`String`] from an existing one by concatenating with
|
2016-01-07 14:54:17 -05:00
|
|
|
|
//! `+`:
|
|
|
|
|
//!
|
2016-10-10 18:15:55 +02:00
|
|
|
|
//! [`String`]: struct.String.html
|
|
|
|
|
//!
|
2016-09-21 17:07:45 +02:00
|
|
|
|
//! ```
|
2016-01-07 14:54:17 -05:00
|
|
|
|
//! let s = "Hello".to_string();
|
|
|
|
|
//!
|
|
|
|
|
//! let message = s + " world!";
|
|
|
|
|
//! ```
|
|
|
|
|
//!
|
2017-08-18 17:17:46 +02:00
|
|
|
|
//! If you have a vector of valid UTF-8 bytes, you can make a [`String`] out of
|
2016-01-07 14:54:17 -05:00
|
|
|
|
//! it. You can do the reverse too.
|
|
|
|
|
//!
|
2016-09-21 17:07:45 +02:00
|
|
|
|
//! ```
|
2016-01-07 14:54:17 -05:00
|
|
|
|
//! let sparkle_heart = vec![240, 159, 146, 150];
|
|
|
|
|
//!
|
|
|
|
|
//! // We know these bytes are valid, so we'll use `unwrap()`.
|
|
|
|
|
//! let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();
|
|
|
|
|
//!
|
|
|
|
|
//! assert_eq!("💖", sparkle_heart);
|
|
|
|
|
//!
|
|
|
|
|
//! let bytes = sparkle_heart.into_bytes();
|
|
|
|
|
//!
|
|
|
|
|
//! assert_eq!(bytes, [240, 159, 146, 150]);
|
|
|
|
|
//! ```
|
2014-04-02 16:54:22 -07:00
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#![stable(feature = "rust1", since = "1.0.0")]
|
2014-12-28 10:29:56 -08:00
|
|
|
|
|
2018-04-05 17:56:46 +02:00
|
|
|
|
use core::char::{decode_utf16, REPLACEMENT_CHARACTER};
|
std: Recreate a `collections` module
As with the previous commit with `librand`, this commit shuffles around some
`collections` code. The new state of the world is similar to that of librand:
* The libcollections crate now only depends on libcore and liballoc.
* The standard library has a new module, `std::collections`. All functionality
of libcollections is reexported through this module.
I would like to stress that this change is purely cosmetic. There are very few
alterations to these primitives.
There are a number of notable points about the new organization:
* std::{str, slice, string, vec} all moved to libcollections. There is no reason
that these primitives shouldn't be necessarily usable in a freestanding
context that has allocation. These are all reexported in their usual places in
the standard library.
* The `hashmap`, and transitively the `lru_cache`, modules no longer reside in
`libcollections`, but rather in libstd. The reason for this is because the
`HashMap::new` contructor requires access to the OSRng for initially seeding
the hash map. Beyond this requirement, there is no reason that the hashmap
could not move to libcollections.
I do, however, have a plan to move the hash map to the collections module. The
`HashMap::new` function could be altered to require that the `H` hasher
parameter ascribe to the `Default` trait, allowing the entire `hashmap` module
to live in libcollections. The key idea would be that the default hasher would
be different in libstd. Something along the lines of:
// src/libstd/collections/mod.rs
pub type HashMap<K, V, H = RandomizedSipHasher> =
core_collections::HashMap<K, V, H>;
This is not possible today because you cannot invoke static methods through
type aliases. If we modified the compiler, however, to allow invocation of
static methods through type aliases, then this type definition would
essentially be switching the default hasher from `SipHasher` in libcollections
to a libstd-defined `RandomizedSipHasher` type. This type's `Default`
implementation would randomly seed the `SipHasher` instance, and otherwise
perform the same as `SipHasher`.
This future state doesn't seem incredibly far off, but until that time comes,
the hashmap module will live in libstd to not compromise on functionality.
* In preparation for the hashmap moving to libcollections, the `hash` module has
moved from libstd to libcollections. A previously snapshotted commit enables a
distinct `Writer` trait to live in the `hash` module which `Hash`
implementations are now parameterized over.
Due to using a custom trait, the `SipHasher` implementation has lost its
specialized methods for writing integers. These can be re-added
backwards-compatibly in the future via default methods if necessary, but the
FNV hashing should satisfy much of the need for speedier hashing.
A list of breaking changes:
* HashMap::{get, get_mut} no longer fails with the key formatted into the error
message with `{:?}`, instead, a generic message is printed. With backtraces,
it should still be not-too-hard to track down errors.
* The HashMap, HashSet, and LruCache types are now available through
std::collections instead of the collections crate.
* Manual implementations of hash should be parameterized over `hash::Writer`
instead of just `Writer`.
[breaking-change]
2014-05-29 18:50:12 -07:00
|
|
|
|
use core::fmt;
|
2014-12-12 18:43:07 -08:00
|
|
|
|
use core::hash;
|
2016-08-13 14:42:36 -04:00
|
|
|
|
use core::iter::{FromIterator, FusedIterator};
|
2018-03-19 09:01:17 +01:00
|
|
|
|
use core::ops::Bound::{Excluded, Included, Unbounded};
|
2018-03-19 09:26:29 +01:00
|
|
|
|
use core::ops::{self, Add, AddAssign, Index, IndexMut, RangeBounds};
|
std: Recreate a `collections` module
As with the previous commit with `librand`, this commit shuffles around some
`collections` code. The new state of the world is similar to that of librand:
* The libcollections crate now only depends on libcore and liballoc.
* The standard library has a new module, `std::collections`. All functionality
of libcollections is reexported through this module.
I would like to stress that this change is purely cosmetic. There are very few
alterations to these primitives.
There are a number of notable points about the new organization:
* std::{str, slice, string, vec} all moved to libcollections. There is no reason
that these primitives shouldn't be necessarily usable in a freestanding
context that has allocation. These are all reexported in their usual places in
the standard library.
* The `hashmap`, and transitively the `lru_cache`, modules no longer reside in
`libcollections`, but rather in libstd. The reason for this is because the
`HashMap::new` contructor requires access to the OSRng for initially seeding
the hash map. Beyond this requirement, there is no reason that the hashmap
could not move to libcollections.
I do, however, have a plan to move the hash map to the collections module. The
`HashMap::new` function could be altered to require that the `H` hasher
parameter ascribe to the `Default` trait, allowing the entire `hashmap` module
to live in libcollections. The key idea would be that the default hasher would
be different in libstd. Something along the lines of:
// src/libstd/collections/mod.rs
pub type HashMap<K, V, H = RandomizedSipHasher> =
core_collections::HashMap<K, V, H>;
This is not possible today because you cannot invoke static methods through
type aliases. If we modified the compiler, however, to allow invocation of
static methods through type aliases, then this type definition would
essentially be switching the default hasher from `SipHasher` in libcollections
to a libstd-defined `RandomizedSipHasher` type. This type's `Default`
implementation would randomly seed the `SipHasher` instance, and otherwise
perform the same as `SipHasher`.
This future state doesn't seem incredibly far off, but until that time comes,
the hashmap module will live in libstd to not compromise on functionality.
* In preparation for the hashmap moving to libcollections, the `hash` module has
moved from libstd to libcollections. A previously snapshotted commit enables a
distinct `Writer` trait to live in the `hash` module which `Hash`
implementations are now parameterized over.
Due to using a custom trait, the `SipHasher` implementation has lost its
specialized methods for writing integers. These can be re-added
backwards-compatibly in the future via default methods if necessary, but the
FNV hashing should satisfy much of the need for speedier hashing.
A list of breaking changes:
* HashMap::{get, get_mut} no longer fails with the key formatted into the error
message with `{:?}`, instead, a generic message is printed. With backtraces,
it should still be not-too-hard to track down errors.
* The HashMap, HashSet, and LruCache types are now available through
std::collections instead of the collections crate.
* Manual implementations of hash should be parameterized over `hash::Writer`
instead of just `Writer`.
[breaking-change]
2014-05-29 18:50:12 -07:00
|
|
|
|
use core::ptr;
|
2015-03-23 14:21:42 +01:00
|
|
|
|
use core::str::pattern::Pattern;
|
2018-04-05 15:55:28 +02:00
|
|
|
|
use core::str::lossy;
|
std: Recreate a `collections` module
As with the previous commit with `librand`, this commit shuffles around some
`collections` code. The new state of the world is similar to that of librand:
* The libcollections crate now only depends on libcore and liballoc.
* The standard library has a new module, `std::collections`. All functionality
of libcollections is reexported through this module.
I would like to stress that this change is purely cosmetic. There are very few
alterations to these primitives.
There are a number of notable points about the new organization:
* std::{str, slice, string, vec} all moved to libcollections. There is no reason
that these primitives shouldn't be necessarily usable in a freestanding
context that has allocation. These are all reexported in their usual places in
the standard library.
* The `hashmap`, and transitively the `lru_cache`, modules no longer reside in
`libcollections`, but rather in libstd. The reason for this is because the
`HashMap::new` contructor requires access to the OSRng for initially seeding
the hash map. Beyond this requirement, there is no reason that the hashmap
could not move to libcollections.
I do, however, have a plan to move the hash map to the collections module. The
`HashMap::new` function could be altered to require that the `H` hasher
parameter ascribe to the `Default` trait, allowing the entire `hashmap` module
to live in libcollections. The key idea would be that the default hasher would
be different in libstd. Something along the lines of:
// src/libstd/collections/mod.rs
pub type HashMap<K, V, H = RandomizedSipHasher> =
core_collections::HashMap<K, V, H>;
This is not possible today because you cannot invoke static methods through
type aliases. If we modified the compiler, however, to allow invocation of
static methods through type aliases, then this type definition would
essentially be switching the default hasher from `SipHasher` in libcollections
to a libstd-defined `RandomizedSipHasher` type. This type's `Default`
implementation would randomly seed the `SipHasher` instance, and otherwise
perform the same as `SipHasher`.
This future state doesn't seem incredibly far off, but until that time comes,
the hashmap module will live in libstd to not compromise on functionality.
* In preparation for the hashmap moving to libcollections, the `hash` module has
moved from libstd to libcollections. A previously snapshotted commit enables a
distinct `Writer` trait to live in the `hash` module which `Hash`
implementations are now parameterized over.
Due to using a custom trait, the `SipHasher` implementation has lost its
specialized methods for writing integers. These can be re-added
backwards-compatibly in the future via default methods if necessary, but the
FNV hashing should satisfy much of the need for speedier hashing.
A list of breaking changes:
* HashMap::{get, get_mut} no longer fails with the key formatted into the error
message with `{:?}`, instead, a generic message is printed. With backtraces,
it should still be not-too-hard to track down errors.
* The HashMap, HashSet, and LruCache types are now available through
std::collections instead of the collections crate.
* Manual implementations of hash should be parameterized over `hash::Writer`
instead of just `Writer`.
[breaking-change]
2014-05-29 18:50:12 -07:00
|
|
|
|
|
2018-04-14 08:13:28 +09:00
|
|
|
|
use alloc::CollectionAllocErr;
|
2016-03-10 21:15:29 +01:00
|
|
|
|
use borrow::{Cow, ToOwned};
|
2018-04-14 08:13:28 +09:00
|
|
|
|
use boxed::Box;
|
2017-06-13 15:52:59 -07:00
|
|
|
|
use str::{self, from_boxed_utf8_unchecked, FromStr, Utf8Error, Chars};
|
2015-07-09 21:57:21 -07:00
|
|
|
|
use vec::Vec;
|
2014-04-02 16:54:22 -07:00
|
|
|
|
|
2015-12-01 13:39:48 -05:00
|
|
|
|
/// A UTF-8 encoded, growable string.
|
|
|
|
|
///
|
|
|
|
|
/// The `String` type is the most common string type that has ownership over the
|
|
|
|
|
/// contents of the string. It has a close relationship with its borrowed
|
|
|
|
|
/// counterpart, the primitive [`str`].
|
|
|
|
|
///
|
2016-03-07 23:55:52 -08:00
|
|
|
|
/// [`str`]: ../../std/primitive.str.html
|
2015-12-01 13:39:48 -05:00
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
2017-08-25 23:09:00 +02:00
|
|
|
|
/// You can create a `String` from a literal string with [`String::from`]:
|
2015-12-01 13:39:48 -05:00
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let hello = String::from("Hello, world!");
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// You can append a [`char`] to a `String` with the [`push`] method, and
|
|
|
|
|
/// append a [`&str`] with the [`push_str`] method:
|
2015-12-01 13:39:48 -05:00
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let mut hello = String::from("Hello, ");
|
|
|
|
|
///
|
|
|
|
|
/// hello.push('w');
|
|
|
|
|
/// hello.push_str("orld!");
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
2017-08-25 23:09:00 +02:00
|
|
|
|
/// [`String::from`]: #method.from
|
2016-03-07 23:55:52 -08:00
|
|
|
|
/// [`char`]: ../../std/primitive.char.html
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`push`]: #method.push
|
|
|
|
|
/// [`push_str`]: #method.push_str
|
2015-12-01 13:39:48 -05:00
|
|
|
|
///
|
|
|
|
|
/// If you have a vector of UTF-8 bytes, you can create a `String` from it with
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// the [`from_utf8`] method:
|
2015-12-01 13:39:48 -05:00
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// // some bytes, in a vector
|
|
|
|
|
/// let sparkle_heart = vec![240, 159, 146, 150];
|
|
|
|
|
///
|
|
|
|
|
/// // We know these bytes are valid, so we'll use `unwrap()`.
|
|
|
|
|
/// let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!("💖", sparkle_heart);
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`from_utf8`]: #method.from_utf8
|
2015-12-01 13:39:48 -05:00
|
|
|
|
///
|
|
|
|
|
/// # UTF-8
|
|
|
|
|
///
|
|
|
|
|
/// `String`s are always valid UTF-8. This has a few implications, the first of
|
|
|
|
|
/// which is that if you need a non-UTF-8 string, consider [`OsString`]. It is
|
|
|
|
|
/// similar, but without the UTF-8 constraint. The second implication is that
|
|
|
|
|
/// you cannot index into a `String`:
|
|
|
|
|
///
|
2017-06-20 15:15:16 +08:00
|
|
|
|
/// ```compile_fail,E0277
|
2015-12-01 13:39:48 -05:00
|
|
|
|
/// let s = "hello";
|
|
|
|
|
///
|
|
|
|
|
/// println!("The first letter of s is {}", s[0]); // ERROR!!!
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
2016-03-07 23:55:52 -08:00
|
|
|
|
/// [`OsString`]: ../../std/ffi/struct.OsString.html
|
2015-12-01 13:39:48 -05:00
|
|
|
|
///
|
|
|
|
|
/// Indexing is intended to be a constant-time operation, but UTF-8 encoding
|
2016-08-21 22:51:37 +02:00
|
|
|
|
/// does not allow us to do this. Furthermore, it's not clear what sort of
|
2015-12-01 13:39:48 -05:00
|
|
|
|
/// thing the index should return: a byte, a codepoint, or a grapheme cluster.
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// The [`bytes`] and [`chars`] methods return iterators over the first
|
2015-12-01 13:39:48 -05:00
|
|
|
|
/// two, respectively.
|
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`bytes`]: #method.bytes
|
|
|
|
|
/// [`chars`]: #method.chars
|
2015-12-01 13:39:48 -05:00
|
|
|
|
///
|
|
|
|
|
/// # Deref
|
|
|
|
|
///
|
|
|
|
|
/// `String`s implement [`Deref`]`<Target=str>`, and so inherit all of [`str`]'s
|
2017-08-04 12:25:05 -04:00
|
|
|
|
/// methods. In addition, this means that you can pass a `String` to a
|
2015-12-01 13:39:48 -05:00
|
|
|
|
/// function which takes a [`&str`] by using an ampersand (`&`):
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// fn takes_str(s: &str) { }
|
|
|
|
|
///
|
|
|
|
|
/// let s = String::from("Hello");
|
|
|
|
|
///
|
|
|
|
|
/// takes_str(&s);
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
|
|
|
|
/// This will create a [`&str`] from the `String` and pass it in. This
|
|
|
|
|
/// conversion is very inexpensive, and so generally, functions will accept
|
2017-08-04 12:25:05 -04:00
|
|
|
|
/// [`&str`]s as arguments unless they need a `String` for some specific
|
|
|
|
|
/// reason.
|
2015-12-01 13:39:48 -05:00
|
|
|
|
///
|
2017-08-07 13:56:20 -04:00
|
|
|
|
/// In certain cases Rust doesn't have enough information to make this
|
2017-08-18 17:17:46 +02:00
|
|
|
|
/// conversion, known as [`Deref`] coercion. In the following example a string
|
|
|
|
|
/// slice [`&'a str`][`&str`] implements the trait `TraitExample`, and the function
|
2017-08-07 13:56:20 -04:00
|
|
|
|
/// `example_func` takes anything that implements the trait. In this case Rust
|
|
|
|
|
/// would need to make two implicit conversions, which Rust doesn't have the
|
|
|
|
|
/// means to do. For that reason, the following example will not compile.
|
2017-08-04 12:25:05 -04:00
|
|
|
|
///
|
|
|
|
|
/// ```compile_fail,E0277
|
|
|
|
|
/// trait TraitExample {}
|
|
|
|
|
///
|
|
|
|
|
/// impl<'a> TraitExample for &'a str {}
|
|
|
|
|
///
|
|
|
|
|
/// fn example_func<A: TraitExample>(example_arg: A) {}
|
|
|
|
|
///
|
|
|
|
|
/// fn main() {
|
|
|
|
|
/// let example_string = String::from("example_string");
|
|
|
|
|
/// example_func(&example_string);
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
2017-08-08 14:57:34 -04:00
|
|
|
|
/// There are two options that would work instead. The first would be to
|
|
|
|
|
/// change the line `example_func(&example_string);` to
|
2017-08-18 17:17:46 +02:00
|
|
|
|
/// `example_func(example_string.as_str());`, using the method [`as_str()`]
|
2017-08-08 14:57:34 -04:00
|
|
|
|
/// to explicitly extract the string slice containing the string. The second
|
|
|
|
|
/// way changes `example_func(&example_string);` to
|
|
|
|
|
/// `example_func(&*example_string);`. In this case we are dereferencing a
|
2017-08-18 17:17:46 +02:00
|
|
|
|
/// `String` to a [`str`][`&str`], then referencing the [`str`][`&str`] back to
|
|
|
|
|
/// [`&str`]. The second way is more idiomatic, however both work to do the
|
|
|
|
|
/// conversion explicitly rather than relying on the implicit conversion.
|
2015-12-01 13:39:48 -05:00
|
|
|
|
///
|
|
|
|
|
/// # Representation
|
|
|
|
|
///
|
|
|
|
|
/// A `String` is made up of three components: a pointer to some bytes, a
|
|
|
|
|
/// length, and a capacity. The pointer points to an internal buffer `String`
|
|
|
|
|
/// uses to store its data. The length is the number of bytes currently stored
|
|
|
|
|
/// in the buffer, and the capacity is the size of the buffer in bytes. As such,
|
|
|
|
|
/// the length will always be less than or equal to the capacity.
|
|
|
|
|
///
|
|
|
|
|
/// This buffer is always stored on the heap.
|
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// You can look at these with the [`as_ptr`], [`len`], and [`capacity`]
|
2015-12-01 13:39:48 -05:00
|
|
|
|
/// methods:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// use std::mem;
|
|
|
|
|
///
|
|
|
|
|
/// let story = String::from("Once upon a time...");
|
|
|
|
|
///
|
|
|
|
|
/// let ptr = story.as_ptr();
|
|
|
|
|
/// let len = story.len();
|
|
|
|
|
/// let capacity = story.capacity();
|
|
|
|
|
///
|
2016-05-12 21:49:14 +02:00
|
|
|
|
/// // story has nineteen bytes
|
2015-12-01 13:39:48 -05:00
|
|
|
|
/// assert_eq!(19, len);
|
|
|
|
|
///
|
|
|
|
|
/// // Now that we have our parts, we throw the story away.
|
|
|
|
|
/// mem::forget(story);
|
|
|
|
|
///
|
|
|
|
|
/// // We can re-build a String out of ptr, len, and capacity. This is all
|
2016-02-09 11:52:39 -05:00
|
|
|
|
/// // unsafe because we are responsible for making sure the components are
|
2015-12-01 13:39:48 -05:00
|
|
|
|
/// // valid:
|
|
|
|
|
/// let s = unsafe { String::from_raw_parts(ptr as *mut _, len, capacity) } ;
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(String::from("Once upon a time..."), s);
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`as_ptr`]: #method.as_ptr
|
|
|
|
|
/// [`len`]: #method.len
|
|
|
|
|
/// [`capacity`]: #method.capacity
|
2015-12-01 13:39:48 -05:00
|
|
|
|
///
|
|
|
|
|
/// If a `String` has enough capacity, adding elements to it will not
|
|
|
|
|
/// re-allocate. For example, consider this program:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let mut s = String::new();
|
|
|
|
|
///
|
|
|
|
|
/// println!("{}", s.capacity());
|
|
|
|
|
///
|
|
|
|
|
/// for _ in 0..5 {
|
|
|
|
|
/// s.push_str("hello");
|
|
|
|
|
/// println!("{}", s.capacity());
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
|
|
|
|
/// This will output the following:
|
|
|
|
|
///
|
|
|
|
|
/// ```text
|
|
|
|
|
/// 0
|
|
|
|
|
/// 5
|
|
|
|
|
/// 10
|
|
|
|
|
/// 20
|
|
|
|
|
/// 20
|
|
|
|
|
/// 40
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
|
|
|
|
/// At first, we have no memory allocated at all, but as we append to the
|
|
|
|
|
/// string, it increases its capacity appropriately. If we instead use the
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`with_capacity`] method to allocate the correct capacity initially:
|
2015-12-01 13:39:48 -05:00
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let mut s = String::with_capacity(25);
|
|
|
|
|
///
|
|
|
|
|
/// println!("{}", s.capacity());
|
|
|
|
|
///
|
|
|
|
|
/// for _ in 0..5 {
|
|
|
|
|
/// s.push_str("hello");
|
|
|
|
|
/// println!("{}", s.capacity());
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`with_capacity`]: #method.with_capacity
|
2015-12-01 13:39:48 -05:00
|
|
|
|
///
|
|
|
|
|
/// We end up with a different output:
|
|
|
|
|
///
|
|
|
|
|
/// ```text
|
|
|
|
|
/// 25
|
|
|
|
|
/// 25
|
|
|
|
|
/// 25
|
|
|
|
|
/// 25
|
|
|
|
|
/// 25
|
|
|
|
|
/// 25
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
|
|
|
|
/// Here, there's no need to allocate more memory inside the loop.
|
2017-08-18 17:17:46 +02:00
|
|
|
|
///
|
|
|
|
|
/// [`&str`]: ../../std/primitive.str.html
|
|
|
|
|
/// [`Deref`]: ../../std/ops/trait.Deref.html
|
|
|
|
|
/// [`as_str()`]: struct.String.html#method.as_str
|
2015-09-23 08:49:50 -04:00
|
|
|
|
#[derive(PartialOrd, Eq, Ord)]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-05-22 16:57:53 -07:00
|
|
|
|
pub struct String {
|
2014-04-02 16:54:22 -07:00
|
|
|
|
vec: Vec<u8>,
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-30 15:48:28 -05:00
|
|
|
|
/// A possible error value when converting a `String` from a UTF-8 byte vector.
|
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// This type is the error type for the [`from_utf8`] method on [`String`]. It
|
2015-11-30 15:48:28 -05:00
|
|
|
|
/// is designed in such a way to carefully avoid reallocations: the
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`into_bytes`] method will give back the byte vector that was used in the
|
2015-11-30 15:48:28 -05:00
|
|
|
|
/// conversion attempt.
|
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`from_utf8`]: struct.String.html#method.from_utf8
|
2015-11-30 15:48:28 -05:00
|
|
|
|
/// [`String`]: struct.String.html
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`into_bytes`]: struct.FromUtf8Error.html#method.into_bytes
|
2015-11-30 15:48:28 -05:00
|
|
|
|
///
|
|
|
|
|
/// The [`Utf8Error`] type provided by [`std::str`] represents an error that may
|
|
|
|
|
/// occur when converting a slice of [`u8`]s to a [`&str`]. In this sense, it's
|
|
|
|
|
/// an analogue to `FromUtf8Error`, and you can get one from a `FromUtf8Error`
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// through the [`utf8_error`] method.
|
2015-11-30 15:48:28 -05:00
|
|
|
|
///
|
2016-03-07 23:55:52 -08:00
|
|
|
|
/// [`Utf8Error`]: ../../std/str/struct.Utf8Error.html
|
|
|
|
|
/// [`std::str`]: ../../std/str/index.html
|
|
|
|
|
/// [`u8`]: ../../std/primitive.u8.html
|
|
|
|
|
/// [`&str`]: ../../std/primitive.str.html
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`utf8_error`]: #method.utf8_error
|
2015-11-30 15:48:28 -05:00
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// // some invalid bytes, in a vector
|
|
|
|
|
/// let bytes = vec![0, 159];
|
|
|
|
|
///
|
|
|
|
|
/// let value = String::from_utf8(bytes);
|
|
|
|
|
///
|
|
|
|
|
/// assert!(value.is_err());
|
|
|
|
|
/// assert_eq!(vec![0, 159], value.unwrap_err().into_bytes());
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-01-28 08:34:18 -05:00
|
|
|
|
#[derive(Debug)]
|
2014-12-28 10:29:56 -08:00
|
|
|
|
pub struct FromUtf8Error {
|
|
|
|
|
bytes: Vec<u8>,
|
|
|
|
|
error: Utf8Error,
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-30 15:48:28 -05:00
|
|
|
|
/// A possible error value when converting a `String` from a UTF-16 byte slice.
|
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// This type is the error type for the [`from_utf16`] method on [`String`].
|
2015-11-30 15:48:28 -05:00
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`from_utf16`]: struct.String.html#method.from_utf16
|
2015-11-30 15:48:28 -05:00
|
|
|
|
/// [`String`]: struct.String.html
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// // 𝄞mu<invalid>ic
|
|
|
|
|
/// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
|
|
|
|
|
/// 0xD800, 0x0069, 0x0063];
|
|
|
|
|
///
|
|
|
|
|
/// assert!(String::from_utf16(v).is_err());
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-01-28 08:34:18 -05:00
|
|
|
|
#[derive(Debug)]
|
2014-12-28 10:29:56 -08:00
|
|
|
|
pub struct FromUtf16Error(());
|
|
|
|
|
|
2014-05-22 16:57:53 -07:00
|
|
|
|
impl String {
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Creates a new empty `String`.
|
|
|
|
|
///
|
|
|
|
|
/// Given that the `String` is empty, this will not allocate any initial
|
|
|
|
|
/// buffer. While that means that this initial operation is very
|
2018-02-22 14:21:54 -05:00
|
|
|
|
/// inexpensive, it may cause excessive allocation later when you add
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// data. If you have an idea of how much data the `String` will hold,
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// consider the [`with_capacity`] method to prevent excessive
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// re-allocation.
|
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`with_capacity`]: #method.with_capacity
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// let s = String::new();
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2014-04-02 16:54:22 -07:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-05-22 16:57:53 -07:00
|
|
|
|
pub fn new() -> String {
|
2015-11-24 11:23:48 +13:00
|
|
|
|
String { vec: Vec::new() }
|
2014-04-02 16:54:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Creates a new empty `String` with a particular capacity.
|
|
|
|
|
///
|
|
|
|
|
/// `String`s have an internal buffer to hold their data. The capacity is
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// the length of that buffer, and can be queried with the [`capacity`]
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// method. This method creates an empty `String`, but one with an initial
|
|
|
|
|
/// buffer that can hold `capacity` bytes. This is useful when you may be
|
|
|
|
|
/// appending a bunch of data to the `String`, reducing the number of
|
|
|
|
|
/// reallocations it needs to do.
|
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`capacity`]: #method.capacity
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
|
|
|
|
/// If the given capacity is `0`, no allocation will occur, and this method
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// is identical to the [`new`] method.
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`new`]: #method.new
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
|
|
|
|
/// let mut s = String::with_capacity(10);
|
2015-11-03 14:49:33 +00:00
|
|
|
|
///
|
|
|
|
|
/// // The String contains no chars, even though it has capacity for more
|
|
|
|
|
/// assert_eq!(s.len(), 0);
|
|
|
|
|
///
|
|
|
|
|
/// // These are all done without reallocating...
|
|
|
|
|
/// let cap = s.capacity();
|
|
|
|
|
/// for i in 0..10 {
|
|
|
|
|
/// s.push('a');
|
|
|
|
|
/// }
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(s.capacity(), cap);
|
|
|
|
|
///
|
|
|
|
|
/// // ...but this may make the vector reallocate
|
|
|
|
|
/// s.push('a');
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2014-04-02 16:54:22 -07:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-04 21:17:19 -05:00
|
|
|
|
pub fn with_capacity(capacity: usize) -> String {
|
2015-11-24 11:23:48 +13:00
|
|
|
|
String { vec: Vec::with_capacity(capacity) }
|
2014-04-02 16:54:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
2015-03-18 09:36:18 -07:00
|
|
|
|
// HACK(japaric): with cfg(test) the inherent `[T]::to_vec` method, which is
|
|
|
|
|
// required for this method definition, is not available. Since we don't
|
|
|
|
|
// require this method for testing purposes, I'll just stub it
|
2015-03-13 19:44:02 -05:00
|
|
|
|
// NB see the slice::hack module in slice.rs for more information
|
2015-03-11 19:44:02 -05:00
|
|
|
|
#[inline]
|
|
|
|
|
#[cfg(test)]
|
2015-03-13 19:44:02 -05:00
|
|
|
|
pub fn from_str(_: &str) -> String {
|
|
|
|
|
panic!("not available with cfg(test)");
|
2015-03-11 19:44:02 -05:00
|
|
|
|
}
|
|
|
|
|
|
2015-10-02 14:36:02 -04:00
|
|
|
|
/// Converts a vector of bytes to a `String`.
|
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// A string slice ([`&str`]) is made of bytes ([`u8`]), and a vector of bytes
|
|
|
|
|
/// ([`Vec<u8>`]) is made of bytes, so this function converts between the
|
2015-10-02 14:36:02 -04:00
|
|
|
|
/// two. Not all byte slices are valid `String`s, however: `String`
|
|
|
|
|
/// requires that it is valid UTF-8. `from_utf8()` checks to ensure that
|
|
|
|
|
/// the bytes are valid UTF-8, and then does the conversion.
|
|
|
|
|
///
|
|
|
|
|
/// If you are sure that the byte slice is valid UTF-8, and you don't want
|
|
|
|
|
/// to incur the overhead of the validity check, there is an unsafe version
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// of this function, [`from_utf8_unchecked`], which has the same behavior
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// but skips the check.
|
2015-10-02 14:36:02 -04:00
|
|
|
|
///
|
|
|
|
|
/// This method will take care to not copy the vector, for efficiency's
|
|
|
|
|
/// sake.
|
|
|
|
|
///
|
2017-08-18 17:17:46 +02:00
|
|
|
|
/// If you need a [`&str`] instead of a `String`, consider
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`str::from_utf8`].
|
2015-10-02 14:36:02 -04:00
|
|
|
|
///
|
2017-03-03 01:24:19 -05:00
|
|
|
|
/// The inverse of this method is [`as_bytes`].
|
|
|
|
|
///
|
2016-02-01 21:41:29 -05:00
|
|
|
|
/// # Errors
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
|
///
|
2017-08-18 17:17:46 +02:00
|
|
|
|
/// Returns [`Err`] if the slice is not UTF-8 with a description as to why the
|
2015-10-02 14:36:02 -04:00
|
|
|
|
/// provided bytes are not UTF-8. The vector you moved in is also included.
|
2014-06-30 16:41:30 +02:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-06-30 16:41:30 +02:00
|
|
|
|
///
|
2015-10-02 14:36:02 -04:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
|
/// ```
|
2015-10-02 14:36:02 -04:00
|
|
|
|
/// // some bytes, in a vector
|
|
|
|
|
/// let sparkle_heart = vec![240, 159, 146, 150];
|
|
|
|
|
///
|
2015-12-01 13:39:48 -05:00
|
|
|
|
/// // We know these bytes are valid, so we'll use `unwrap()`.
|
2015-10-02 14:36:02 -04:00
|
|
|
|
/// let sparkle_heart = String::from_utf8(sparkle_heart).unwrap();
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!("💖", sparkle_heart);
|
2014-06-30 16:41:30 +02:00
|
|
|
|
/// ```
|
2015-10-02 14:36:02 -04:00
|
|
|
|
///
|
|
|
|
|
/// Incorrect bytes:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// // some invalid bytes, in a vector
|
|
|
|
|
/// let sparkle_heart = vec![0, 159, 146, 150];
|
|
|
|
|
///
|
|
|
|
|
/// assert!(String::from_utf8(sparkle_heart).is_err());
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// See the docs for [`FromUtf8Error`] for more details on what you can do
|
|
|
|
|
/// with this error.
|
2015-10-02 14:36:02 -04:00
|
|
|
|
///
|
2017-08-18 17:17:46 +02:00
|
|
|
|
/// [`from_utf8_unchecked`]: struct.String.html#method.from_utf8_unchecked
|
|
|
|
|
/// [`&str`]: ../../std/primitive.str.html
|
|
|
|
|
/// [`u8`]: ../../std/primitive.u8.html
|
|
|
|
|
/// [`Vec<u8>`]: ../../std/vec/struct.Vec.html
|
|
|
|
|
/// [`str::from_utf8`]: ../../std/str/fn.from_utf8.html
|
|
|
|
|
/// [`as_bytes`]: struct.String.html#method.as_bytes
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// [`FromUtf8Error`]: struct.FromUtf8Error.html
|
2017-08-18 17:17:46 +02:00
|
|
|
|
/// [`Err`]: ../../stdresult/enum.Result.html#variant.Err
|
2014-04-10 20:55:34 +10:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-28 10:29:56 -08:00
|
|
|
|
pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> {
|
2015-02-01 21:53:25 -05:00
|
|
|
|
match str::from_utf8(&vec) {
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
|
Ok(..) => Ok(String { vec: vec }),
|
2015-11-24 11:23:48 +13:00
|
|
|
|
Err(e) => {
|
|
|
|
|
Err(FromUtf8Error {
|
|
|
|
|
bytes: vec,
|
|
|
|
|
error: e,
|
|
|
|
|
})
|
|
|
|
|
}
|
2014-04-10 20:55:34 +10:00
|
|
|
|
}
|
|
|
|
|
}
|
2014-07-10 18:21:16 +02:00
|
|
|
|
|
2016-02-08 17:10:55 -05:00
|
|
|
|
/// Converts a slice of bytes to a string, including invalid characters.
|
2015-10-02 14:36:02 -04:00
|
|
|
|
///
|
2016-02-08 17:10:55 -05:00
|
|
|
|
/// Strings are made of bytes ([`u8`]), and a slice of bytes
|
|
|
|
|
/// ([`&[u8]`][byteslice]) is made of bytes, so this function converts
|
|
|
|
|
/// between the two. Not all byte slices are valid strings, however: strings
|
|
|
|
|
/// are required to be valid UTF-8. During this conversion,
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// `from_utf8_lossy()` will replace any invalid UTF-8 sequences with
|
2015-10-02 14:36:02 -04:00
|
|
|
|
/// `U+FFFD REPLACEMENT CHARACTER`, which looks like this: <20>
|
|
|
|
|
///
|
2016-03-07 23:55:52 -08:00
|
|
|
|
/// [`u8`]: ../../std/primitive.u8.html
|
|
|
|
|
/// [byteslice]: ../../std/primitive.slice.html
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2015-10-02 14:36:02 -04:00
|
|
|
|
/// If you are sure that the byte slice is valid UTF-8, and you don't want
|
|
|
|
|
/// to incur the overhead of the conversion, there is an unsafe version
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// of this function, [`from_utf8_unchecked`], which has the same behavior
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// but skips the checks.
|
2015-10-02 14:36:02 -04:00
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`from_utf8_unchecked`]: struct.String.html#method.from_utf8_unchecked
|
2015-10-02 14:36:02 -04:00
|
|
|
|
///
|
2016-02-08 17:10:55 -05:00
|
|
|
|
/// This function returns a [`Cow<'a, str>`]. If our byte slice is invalid
|
|
|
|
|
/// UTF-8, then we need to insert the replacement characters, which will
|
|
|
|
|
/// change the size of the string, and hence, require a `String`. But if
|
|
|
|
|
/// it's already valid UTF-8, we don't need a new allocation. This return
|
|
|
|
|
/// type allows us to handle both cases.
|
2015-10-02 14:36:02 -04:00
|
|
|
|
///
|
2016-03-07 23:55:52 -08:00
|
|
|
|
/// [`Cow<'a, str>`]: ../../std/borrow/enum.Cow.html
|
2014-07-10 18:21:16 +02:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-07-10 18:21:16 +02:00
|
|
|
|
///
|
2015-10-02 14:36:02 -04:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// // some bytes, in a vector
|
|
|
|
|
/// let sparkle_heart = vec![240, 159, 146, 150];
|
|
|
|
|
///
|
2016-02-08 17:10:55 -05:00
|
|
|
|
/// let sparkle_heart = String::from_utf8_lossy(&sparkle_heart);
|
2015-10-02 14:36:02 -04:00
|
|
|
|
///
|
|
|
|
|
/// assert_eq!("💖", sparkle_heart);
|
2015-03-12 22:42:38 -04:00
|
|
|
|
/// ```
|
2015-10-02 14:36:02 -04:00
|
|
|
|
///
|
|
|
|
|
/// Incorrect bytes:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// // some invalid bytes
|
2014-07-10 18:21:16 +02:00
|
|
|
|
/// let input = b"Hello \xF0\x90\x80World";
|
2014-07-04 22:38:13 +02:00
|
|
|
|
/// let output = String::from_utf8_lossy(input);
|
2015-10-02 14:36:02 -04:00
|
|
|
|
///
|
|
|
|
|
/// assert_eq!("Hello <20>World", output);
|
2014-07-10 18:21:16 +02:00
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-11 23:16:32 -08:00
|
|
|
|
pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str> {
|
2017-06-12 20:07:54 +03:00
|
|
|
|
let mut iter = lossy::Utf8Lossy::from_bytes(v).chunks();
|
2014-07-10 18:21:16 +02:00
|
|
|
|
|
2017-06-12 20:07:54 +03:00
|
|
|
|
let (first_valid, first_broken) = if let Some(chunk) = iter.next() {
|
|
|
|
|
let lossy::Utf8LossyChunk { valid, broken } = chunk;
|
|
|
|
|
if valid.len() == v.len() {
|
|
|
|
|
debug_assert!(broken.is_empty());
|
|
|
|
|
return Cow::Borrowed(valid);
|
|
|
|
|
}
|
|
|
|
|
(valid, broken)
|
|
|
|
|
} else {
|
|
|
|
|
return Cow::Borrowed("");
|
|
|
|
|
};
|
2014-07-10 18:21:16 +02:00
|
|
|
|
|
2017-06-12 20:07:54 +03:00
|
|
|
|
const REPLACEMENT: &'static str = "\u{FFFD}";
|
2014-07-10 18:21:16 +02:00
|
|
|
|
|
2017-06-12 20:07:54 +03:00
|
|
|
|
let mut res = String::with_capacity(v.len());
|
|
|
|
|
res.push_str(first_valid);
|
|
|
|
|
if !first_broken.is_empty() {
|
|
|
|
|
res.push_str(REPLACEMENT);
|
2014-07-10 18:21:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
2017-06-12 20:07:54 +03:00
|
|
|
|
for lossy::Utf8LossyChunk { valid, broken } in iter {
|
|
|
|
|
res.push_str(valid);
|
|
|
|
|
if !broken.is_empty() {
|
|
|
|
|
res.push_str(REPLACEMENT);
|
2014-07-10 18:21:16 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-06-12 20:07:54 +03:00
|
|
|
|
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
|
Cow::Owned(res)
|
2014-07-10 18:21:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
2017-08-18 17:17:46 +02:00
|
|
|
|
/// Decode a UTF-16 encoded vector `v` into a `String`, returning [`Err`]
|
2014-07-10 17:43:03 +02:00
|
|
|
|
/// if `v` contains any invalid data.
|
|
|
|
|
///
|
2017-11-21 15:33:45 +01:00
|
|
|
|
/// [`Err`]: ../../std/result/enum.Result.html#variant.Err
|
2017-08-18 17:17:46 +02:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-07-10 17:43:03 +02:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
|
/// ```
|
2014-07-04 22:38:13 +02:00
|
|
|
|
/// // 𝄞music
|
2015-11-30 15:48:28 -05:00
|
|
|
|
/// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
|
|
|
|
|
/// 0x0073, 0x0069, 0x0063];
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// assert_eq!(String::from("𝄞music"),
|
|
|
|
|
/// String::from_utf16(v).unwrap());
|
2014-07-10 17:43:03 +02:00
|
|
|
|
///
|
2014-07-04 22:38:13 +02:00
|
|
|
|
/// // 𝄞mu<invalid>ic
|
2015-11-30 15:48:28 -05:00
|
|
|
|
/// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
|
|
|
|
|
/// 0xD800, 0x0069, 0x0063];
|
2014-12-28 10:29:56 -08:00
|
|
|
|
/// assert!(String::from_utf16(v).is_err());
|
2014-07-10 17:43:03 +02:00
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-28 10:29:56 -08:00
|
|
|
|
pub fn from_utf16(v: &[u16]) -> Result<String, FromUtf16Error> {
|
2015-08-13 18:39:46 +02:00
|
|
|
|
decode_utf16(v.iter().cloned()).collect::<Result<_, _>>().map_err(|_| FromUtf16Error(()))
|
2014-07-10 17:43:03 +02:00
|
|
|
|
}
|
2014-07-10 18:21:16 +02:00
|
|
|
|
|
2017-08-18 17:17:46 +02:00
|
|
|
|
/// Decode a UTF-16 encoded slice `v` into a `String`, replacing
|
2014-07-10 17:53:51 +02:00
|
|
|
|
/// invalid data with the replacement character (U+FFFD).
|
|
|
|
|
///
|
2017-09-14 15:34:31 -04:00
|
|
|
|
/// Unlike [`from_utf8_lossy`] which returns a [`Cow<'a, str>`],
|
|
|
|
|
/// `from_utf16_lossy` returns a `String` since the UTF-16 to UTF-8
|
|
|
|
|
/// conversion requires a memory allocation.
|
|
|
|
|
///
|
|
|
|
|
/// [`from_utf8_lossy`]: #method.from_utf8_lossy
|
|
|
|
|
/// [`Cow<'a, str>`]: ../borrow/enum.Cow.html
|
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
|
/// ```
|
2014-07-04 22:38:13 +02:00
|
|
|
|
/// // 𝄞mus<invalid>ic<invalid>
|
2014-11-17 21:39:01 +13:00
|
|
|
|
/// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
|
|
|
|
|
/// 0x0073, 0xDD1E, 0x0069, 0x0063,
|
|
|
|
|
/// 0xD834];
|
2014-07-10 17:53:51 +02:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// assert_eq!(String::from("𝄞mus\u{FFFD}ic\u{FFFD}"),
|
|
|
|
|
/// String::from_utf16_lossy(v));
|
2014-07-10 17:53:51 +02:00
|
|
|
|
/// ```
|
2015-01-10 11:07:14 +01:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-07-10 17:53:51 +02:00
|
|
|
|
pub fn from_utf16_lossy(v: &[u16]) -> String {
|
2015-08-13 18:39:46 +02:00
|
|
|
|
decode_utf16(v.iter().cloned()).map(|r| r.unwrap_or(REPLACEMENT_CHARACTER)).collect()
|
2014-07-10 17:53:51 +02:00
|
|
|
|
}
|
2014-07-04 22:18:11 +02:00
|
|
|
|
|
2014-11-20 10:11:15 -08:00
|
|
|
|
/// Creates a new `String` from a length, capacity, and pointer.
|
|
|
|
|
///
|
2015-10-23 11:42:14 -04:00
|
|
|
|
/// # Safety
|
2015-03-10 22:47:08 -04:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// This is highly unsafe, due to the number of invariants that aren't
|
|
|
|
|
/// checked:
|
2015-07-02 13:00:58 -04:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// * The memory at `ptr` needs to have been previously allocated by the
|
|
|
|
|
/// same allocator the standard library uses.
|
|
|
|
|
/// * `length` needs to be less than or equal to `capacity`.
|
|
|
|
|
/// * `capacity` needs to be the correct value.
|
|
|
|
|
///
|
|
|
|
|
/// Violating these may cause problems like corrupting the allocator's
|
2017-08-11 20:34:14 +02:00
|
|
|
|
/// internal data structures.
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2016-07-17 10:52:59 -04:00
|
|
|
|
/// The ownership of `ptr` is effectively transferred to the
|
|
|
|
|
/// `String` which may then deallocate, reallocate or change the
|
|
|
|
|
/// contents of memory pointed to by the pointer at will. Ensure
|
|
|
|
|
/// that nothing else uses the pointer after calling this
|
|
|
|
|
/// function.
|
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// use std::mem;
|
|
|
|
|
///
|
|
|
|
|
/// unsafe {
|
|
|
|
|
/// let s = String::from("hello");
|
|
|
|
|
/// let ptr = s.as_ptr();
|
|
|
|
|
/// let len = s.len();
|
|
|
|
|
/// let capacity = s.capacity();
|
|
|
|
|
///
|
|
|
|
|
/// mem::forget(s);
|
|
|
|
|
///
|
|
|
|
|
/// let s = String::from_raw_parts(ptr as *mut _, len, capacity);
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(String::from("hello"), s);
|
|
|
|
|
/// }
|
|
|
|
|
/// ```
|
2014-11-20 10:11:15 -08:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-04 21:17:19 -05:00
|
|
|
|
pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String {
|
2015-11-24 11:23:48 +13:00
|
|
|
|
String { vec: Vec::from_raw_parts(buf, length, capacity) }
|
2014-11-20 10:11:15 -08:00
|
|
|
|
}
|
|
|
|
|
|
2015-10-02 14:36:02 -04:00
|
|
|
|
/// Converts a vector of bytes to a `String` without checking that the
|
|
|
|
|
/// string contains valid UTF-8.
|
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// See the safe version, [`from_utf8`], for more details.
|
2015-10-02 14:36:02 -04:00
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`from_utf8`]: struct.String.html#method.from_utf8
|
2015-10-02 14:36:02 -04:00
|
|
|
|
///
|
2015-10-23 11:42:14 -04:00
|
|
|
|
/// # Safety
|
2015-10-02 14:36:02 -04:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// This function is unsafe because it does not check that the bytes passed
|
|
|
|
|
/// to it are valid UTF-8. If this constraint is violated, it may cause
|
|
|
|
|
/// memory unsafety issues with future users of the `String`, as the rest of
|
|
|
|
|
/// the standard library assumes that `String`s are valid UTF-8.
|
2015-10-02 14:36:02 -04:00
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// // some bytes, in a vector
|
|
|
|
|
/// let sparkle_heart = vec![240, 159, 146, 150];
|
|
|
|
|
///
|
|
|
|
|
/// let sparkle_heart = unsafe {
|
|
|
|
|
/// String::from_utf8_unchecked(sparkle_heart)
|
|
|
|
|
/// };
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!("💖", sparkle_heart);
|
|
|
|
|
/// ```
|
2014-11-20 10:11:15 -08:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-20 10:11:15 -08:00
|
|
|
|
pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String {
|
|
|
|
|
String { vec: bytes }
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Converts a `String` into a byte vector.
|
|
|
|
|
///
|
|
|
|
|
/// This consumes the `String`, so we do not need to copy its contents.
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2015-05-19 03:33:17 +02:00
|
|
|
|
/// let s = String::from("hello");
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// let bytes = s.into_bytes();
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(&[104, 101, 108, 108, 111][..], &bytes[..]);
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2014-04-10 20:55:34 +10:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-04-10 20:55:34 +10:00
|
|
|
|
pub fn into_bytes(self) -> Vec<u8> {
|
|
|
|
|
self.vec
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-13 10:21:32 -04:00
|
|
|
|
/// Extracts a string slice containing the entire string.
|
2017-09-09 09:05:54 +01:00
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let s = String::from("foo");
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!("foo", s.as_str());
|
|
|
|
|
/// ```
|
2015-03-30 15:15:27 -07:00
|
|
|
|
#[inline]
|
2016-01-15 10:07:52 -08:00
|
|
|
|
#[stable(feature = "string_as_str", since = "1.7.0")]
|
2015-03-30 15:15:27 -07:00
|
|
|
|
pub fn as_str(&self) -> &str {
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-09 13:08:26 +01:00
|
|
|
|
/// Converts a `String` into a mutable string slice.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let mut s = String::from("foobar");
|
|
|
|
|
/// let s_mut_str = s.as_mut_str();
|
|
|
|
|
///
|
|
|
|
|
/// s_mut_str.make_ascii_uppercase();
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!("FOOBAR", s_mut_str);
|
|
|
|
|
/// ```
|
2016-01-15 10:07:52 -08:00
|
|
|
|
#[inline]
|
|
|
|
|
#[stable(feature = "string_as_str", since = "1.7.0")]
|
|
|
|
|
pub fn as_mut_str(&mut self) -> &mut str {
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Appends a given string slice onto the end of this `String`.
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2015-05-19 03:33:17 +02:00
|
|
|
|
/// let mut s = String::from("foo");
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// s.push_str("bar");
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
|
|
|
|
/// assert_eq!("foobar", s);
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2014-04-02 16:54:22 -07:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-04-02 16:54:22 -07:00
|
|
|
|
pub fn push_str(&mut self, string: &str) {
|
2015-12-02 17:31:49 -08:00
|
|
|
|
self.vec.extend_from_slice(string.as_bytes())
|
2014-04-02 16:54:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Returns this `String`'s capacity, in bytes.
|
collections: Stabilize String
# Rationale
When dealing with strings, many functions deal with either a `char` (unicode
codepoint) or a byte (utf-8 encoding related). There is often an inconsistent
way in which methods are referred to as to whether they contain "byte", "char",
or nothing in their name. There are also issues open to rename *all* methods to
reflect that they operate on utf8 encodings or bytes (e.g. utf8_len() or
byte_len()).
The current state of String seems to largely be what is desired, so this PR
proposes the following rationale for methods dealing with bytes or characters:
> When constructing a string, the input encoding *must* be mentioned (e.g.
> from_utf8). This makes it clear what exactly the input type is expected to be
> in terms of encoding.
>
> When a method operates on anything related to an *index* within the string
> such as length, capacity, position, etc, the method *implicitly* operates on
> bytes. It is an understood fact that String is a utf-8 encoded string, and
> burdening all methods with "bytes" would be redundant.
>
> When a method operates on the *contents* of a string, such as push() or pop(),
> then "char" is the default type. A String can loosely be thought of as being a
> collection of unicode codepoints, but not all collection-related operations
> make sense because some can be woefully inefficient.
# Method stabilization
The following methods have been marked #[stable]
* The String type itself
* String::new
* String::with_capacity
* String::from_utf16_lossy
* String::into_bytes
* String::as_bytes
* String::len
* String::clear
* String::as_slice
The following methods have been marked #[unstable]
* String::from_utf8 - The error type in the returned `Result` may change to
provide a nicer message when it's `unwrap()`'d
* String::from_utf8_lossy - The returned `MaybeOwned` type still needs
stabilization
* String::from_utf16 - The return type may change to become a `Result` which
includes more contextual information like where the error
occurred.
* String::from_chars - This is equivalent to iter().collect(), but currently not
as ergonomic.
* String::from_char - This method is the equivalent of Vec::from_elem, and has
been marked #[unstable] becuase it can be seen as a
duplicate of iterator-based functionality as well as
possibly being renamed.
* String::push_str - This *can* be emulated with .extend(foo.chars()), but is
less efficient because of decoding/encoding. Due to the
desire to minimize API surface this may be able to be
removed in the future for something possibly generic with
no loss in performance.
* String::grow - This is a duplicate of iterator-based functionality, which may
become more ergonomic in the future.
* String::capacity - This function was just added.
* String::push - This function was just added.
* String::pop - This function was just added.
* String::truncate - The failure conventions around String methods and byte
indices isn't totally clear at this time, so the failure
semantics and return value of this method are subject to
change.
* String::as_mut_vec - the naming of this method may change.
* string::raw::* - these functions are all waiting on [an RFC][2]
[2]: https://github.com/rust-lang/rfcs/pull/240
The following method have been marked #[experimental]
* String::from_str - This function only exists as it's more efficient than
to_string(), but having a less ergonomic function for
performance reasons isn't the greatest reason to keep it
around. Like Vec::push_all, this has been marked
experimental for now.
The following methods have been #[deprecated]
* String::append - This method has been deprecated to remain consistent with the
deprecation of Vec::append. While convenient, it is one of
the only functional-style apis on String, and requires more
though as to whether it belongs as a first-class method or
now (and how it relates to other collections).
* String::from_byte - This is fairly rare functionality and can be emulated with
str::from_utf8 plus an assert plus a call to to_string().
Additionally, String::from_char could possibly be used.
* String::byte_capacity - Renamed to String::capacity due to the rationale
above.
* String::push_char - Renamed to String::push due to the rationale above.
* String::pop_char - Renamed to String::pop due to the rationale above.
* String::push_bytes - There are a number of `unsafe` functions on the `String`
type which allow bypassing utf-8 checks. These have all
been deprecated in favor of calling `.as_mut_vec()` and
then operating directly on the vector returned. These
methods were deprecated because naming them with relation
to other methods was difficult to rationalize and it's
arguably more composable to call .as_mut_vec().
* String::as_mut_bytes - See push_bytes
* String::push_byte - See push_bytes
* String::pop_byte - See push_bytes
* String::shift_byte - See push_bytes
# Reservation methods
This commit does not yet touch the methods for reserving bytes. The methods on
Vec have also not yet been modified. These methods are discussed in the upcoming
[Collections reform RFC][1]
[1]: https://github.com/aturon/rfcs/blob/collections-conventions/active/0000-collections-conventions.md#implicit-growth
2014-09-22 07:12:10 -07:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
collections: Stabilize String
# Rationale
When dealing with strings, many functions deal with either a `char` (unicode
codepoint) or a byte (utf-8 encoding related). There is often an inconsistent
way in which methods are referred to as to whether they contain "byte", "char",
or nothing in their name. There are also issues open to rename *all* methods to
reflect that they operate on utf8 encodings or bytes (e.g. utf8_len() or
byte_len()).
The current state of String seems to largely be what is desired, so this PR
proposes the following rationale for methods dealing with bytes or characters:
> When constructing a string, the input encoding *must* be mentioned (e.g.
> from_utf8). This makes it clear what exactly the input type is expected to be
> in terms of encoding.
>
> When a method operates on anything related to an *index* within the string
> such as length, capacity, position, etc, the method *implicitly* operates on
> bytes. It is an understood fact that String is a utf-8 encoded string, and
> burdening all methods with "bytes" would be redundant.
>
> When a method operates on the *contents* of a string, such as push() or pop(),
> then "char" is the default type. A String can loosely be thought of as being a
> collection of unicode codepoints, but not all collection-related operations
> make sense because some can be woefully inefficient.
# Method stabilization
The following methods have been marked #[stable]
* The String type itself
* String::new
* String::with_capacity
* String::from_utf16_lossy
* String::into_bytes
* String::as_bytes
* String::len
* String::clear
* String::as_slice
The following methods have been marked #[unstable]
* String::from_utf8 - The error type in the returned `Result` may change to
provide a nicer message when it's `unwrap()`'d
* String::from_utf8_lossy - The returned `MaybeOwned` type still needs
stabilization
* String::from_utf16 - The return type may change to become a `Result` which
includes more contextual information like where the error
occurred.
* String::from_chars - This is equivalent to iter().collect(), but currently not
as ergonomic.
* String::from_char - This method is the equivalent of Vec::from_elem, and has
been marked #[unstable] becuase it can be seen as a
duplicate of iterator-based functionality as well as
possibly being renamed.
* String::push_str - This *can* be emulated with .extend(foo.chars()), but is
less efficient because of decoding/encoding. Due to the
desire to minimize API surface this may be able to be
removed in the future for something possibly generic with
no loss in performance.
* String::grow - This is a duplicate of iterator-based functionality, which may
become more ergonomic in the future.
* String::capacity - This function was just added.
* String::push - This function was just added.
* String::pop - This function was just added.
* String::truncate - The failure conventions around String methods and byte
indices isn't totally clear at this time, so the failure
semantics and return value of this method are subject to
change.
* String::as_mut_vec - the naming of this method may change.
* string::raw::* - these functions are all waiting on [an RFC][2]
[2]: https://github.com/rust-lang/rfcs/pull/240
The following method have been marked #[experimental]
* String::from_str - This function only exists as it's more efficient than
to_string(), but having a less ergonomic function for
performance reasons isn't the greatest reason to keep it
around. Like Vec::push_all, this has been marked
experimental for now.
The following methods have been #[deprecated]
* String::append - This method has been deprecated to remain consistent with the
deprecation of Vec::append. While convenient, it is one of
the only functional-style apis on String, and requires more
though as to whether it belongs as a first-class method or
now (and how it relates to other collections).
* String::from_byte - This is fairly rare functionality and can be emulated with
str::from_utf8 plus an assert plus a call to to_string().
Additionally, String::from_char could possibly be used.
* String::byte_capacity - Renamed to String::capacity due to the rationale
above.
* String::push_char - Renamed to String::push due to the rationale above.
* String::pop_char - Renamed to String::pop due to the rationale above.
* String::push_bytes - There are a number of `unsafe` functions on the `String`
type which allow bypassing utf-8 checks. These have all
been deprecated in favor of calling `.as_mut_vec()` and
then operating directly on the vector returned. These
methods were deprecated because naming them with relation
to other methods was difficult to rationalize and it's
arguably more composable to call .as_mut_vec().
* String::as_mut_bytes - See push_bytes
* String::push_byte - See push_bytes
* String::pop_byte - See push_bytes
* String::shift_byte - See push_bytes
# Reservation methods
This commit does not yet touch the methods for reserving bytes. The methods on
Vec have also not yet been modified. These methods are discussed in the upcoming
[Collections reform RFC][1]
[1]: https://github.com/aturon/rfcs/blob/collections-conventions/active/0000-collections-conventions.md#implicit-growth
2014-09-22 07:12:10 -07:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
collections: Stabilize String
# Rationale
When dealing with strings, many functions deal with either a `char` (unicode
codepoint) or a byte (utf-8 encoding related). There is often an inconsistent
way in which methods are referred to as to whether they contain "byte", "char",
or nothing in their name. There are also issues open to rename *all* methods to
reflect that they operate on utf8 encodings or bytes (e.g. utf8_len() or
byte_len()).
The current state of String seems to largely be what is desired, so this PR
proposes the following rationale for methods dealing with bytes or characters:
> When constructing a string, the input encoding *must* be mentioned (e.g.
> from_utf8). This makes it clear what exactly the input type is expected to be
> in terms of encoding.
>
> When a method operates on anything related to an *index* within the string
> such as length, capacity, position, etc, the method *implicitly* operates on
> bytes. It is an understood fact that String is a utf-8 encoded string, and
> burdening all methods with "bytes" would be redundant.
>
> When a method operates on the *contents* of a string, such as push() or pop(),
> then "char" is the default type. A String can loosely be thought of as being a
> collection of unicode codepoints, but not all collection-related operations
> make sense because some can be woefully inefficient.
# Method stabilization
The following methods have been marked #[stable]
* The String type itself
* String::new
* String::with_capacity
* String::from_utf16_lossy
* String::into_bytes
* String::as_bytes
* String::len
* String::clear
* String::as_slice
The following methods have been marked #[unstable]
* String::from_utf8 - The error type in the returned `Result` may change to
provide a nicer message when it's `unwrap()`'d
* String::from_utf8_lossy - The returned `MaybeOwned` type still needs
stabilization
* String::from_utf16 - The return type may change to become a `Result` which
includes more contextual information like where the error
occurred.
* String::from_chars - This is equivalent to iter().collect(), but currently not
as ergonomic.
* String::from_char - This method is the equivalent of Vec::from_elem, and has
been marked #[unstable] becuase it can be seen as a
duplicate of iterator-based functionality as well as
possibly being renamed.
* String::push_str - This *can* be emulated with .extend(foo.chars()), but is
less efficient because of decoding/encoding. Due to the
desire to minimize API surface this may be able to be
removed in the future for something possibly generic with
no loss in performance.
* String::grow - This is a duplicate of iterator-based functionality, which may
become more ergonomic in the future.
* String::capacity - This function was just added.
* String::push - This function was just added.
* String::pop - This function was just added.
* String::truncate - The failure conventions around String methods and byte
indices isn't totally clear at this time, so the failure
semantics and return value of this method are subject to
change.
* String::as_mut_vec - the naming of this method may change.
* string::raw::* - these functions are all waiting on [an RFC][2]
[2]: https://github.com/rust-lang/rfcs/pull/240
The following method have been marked #[experimental]
* String::from_str - This function only exists as it's more efficient than
to_string(), but having a less ergonomic function for
performance reasons isn't the greatest reason to keep it
around. Like Vec::push_all, this has been marked
experimental for now.
The following methods have been #[deprecated]
* String::append - This method has been deprecated to remain consistent with the
deprecation of Vec::append. While convenient, it is one of
the only functional-style apis on String, and requires more
though as to whether it belongs as a first-class method or
now (and how it relates to other collections).
* String::from_byte - This is fairly rare functionality and can be emulated with
str::from_utf8 plus an assert plus a call to to_string().
Additionally, String::from_char could possibly be used.
* String::byte_capacity - Renamed to String::capacity due to the rationale
above.
* String::push_char - Renamed to String::push due to the rationale above.
* String::pop_char - Renamed to String::pop due to the rationale above.
* String::push_bytes - There are a number of `unsafe` functions on the `String`
type which allow bypassing utf-8 checks. These have all
been deprecated in favor of calling `.as_mut_vec()` and
then operating directly on the vector returned. These
methods were deprecated because naming them with relation
to other methods was difficult to rationalize and it's
arguably more composable to call .as_mut_vec().
* String::as_mut_bytes - See push_bytes
* String::push_byte - See push_bytes
* String::pop_byte - See push_bytes
* String::shift_byte - See push_bytes
# Reservation methods
This commit does not yet touch the methods for reserving bytes. The methods on
Vec have also not yet been modified. These methods are discussed in the upcoming
[Collections reform RFC][1]
[1]: https://github.com/aturon/rfcs/blob/collections-conventions/active/0000-collections-conventions.md#implicit-growth
2014-09-22 07:12:10 -07:00
|
|
|
|
/// ```
|
|
|
|
|
/// let s = String::with_capacity(10);
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2014-09-22 08:28:35 -07:00
|
|
|
|
/// assert!(s.capacity() >= 10);
|
collections: Stabilize String
# Rationale
When dealing with strings, many functions deal with either a `char` (unicode
codepoint) or a byte (utf-8 encoding related). There is often an inconsistent
way in which methods are referred to as to whether they contain "byte", "char",
or nothing in their name. There are also issues open to rename *all* methods to
reflect that they operate on utf8 encodings or bytes (e.g. utf8_len() or
byte_len()).
The current state of String seems to largely be what is desired, so this PR
proposes the following rationale for methods dealing with bytes or characters:
> When constructing a string, the input encoding *must* be mentioned (e.g.
> from_utf8). This makes it clear what exactly the input type is expected to be
> in terms of encoding.
>
> When a method operates on anything related to an *index* within the string
> such as length, capacity, position, etc, the method *implicitly* operates on
> bytes. It is an understood fact that String is a utf-8 encoded string, and
> burdening all methods with "bytes" would be redundant.
>
> When a method operates on the *contents* of a string, such as push() or pop(),
> then "char" is the default type. A String can loosely be thought of as being a
> collection of unicode codepoints, but not all collection-related operations
> make sense because some can be woefully inefficient.
# Method stabilization
The following methods have been marked #[stable]
* The String type itself
* String::new
* String::with_capacity
* String::from_utf16_lossy
* String::into_bytes
* String::as_bytes
* String::len
* String::clear
* String::as_slice
The following methods have been marked #[unstable]
* String::from_utf8 - The error type in the returned `Result` may change to
provide a nicer message when it's `unwrap()`'d
* String::from_utf8_lossy - The returned `MaybeOwned` type still needs
stabilization
* String::from_utf16 - The return type may change to become a `Result` which
includes more contextual information like where the error
occurred.
* String::from_chars - This is equivalent to iter().collect(), but currently not
as ergonomic.
* String::from_char - This method is the equivalent of Vec::from_elem, and has
been marked #[unstable] becuase it can be seen as a
duplicate of iterator-based functionality as well as
possibly being renamed.
* String::push_str - This *can* be emulated with .extend(foo.chars()), but is
less efficient because of decoding/encoding. Due to the
desire to minimize API surface this may be able to be
removed in the future for something possibly generic with
no loss in performance.
* String::grow - This is a duplicate of iterator-based functionality, which may
become more ergonomic in the future.
* String::capacity - This function was just added.
* String::push - This function was just added.
* String::pop - This function was just added.
* String::truncate - The failure conventions around String methods and byte
indices isn't totally clear at this time, so the failure
semantics and return value of this method are subject to
change.
* String::as_mut_vec - the naming of this method may change.
* string::raw::* - these functions are all waiting on [an RFC][2]
[2]: https://github.com/rust-lang/rfcs/pull/240
The following method have been marked #[experimental]
* String::from_str - This function only exists as it's more efficient than
to_string(), but having a less ergonomic function for
performance reasons isn't the greatest reason to keep it
around. Like Vec::push_all, this has been marked
experimental for now.
The following methods have been #[deprecated]
* String::append - This method has been deprecated to remain consistent with the
deprecation of Vec::append. While convenient, it is one of
the only functional-style apis on String, and requires more
though as to whether it belongs as a first-class method or
now (and how it relates to other collections).
* String::from_byte - This is fairly rare functionality and can be emulated with
str::from_utf8 plus an assert plus a call to to_string().
Additionally, String::from_char could possibly be used.
* String::byte_capacity - Renamed to String::capacity due to the rationale
above.
* String::push_char - Renamed to String::push due to the rationale above.
* String::pop_char - Renamed to String::pop due to the rationale above.
* String::push_bytes - There are a number of `unsafe` functions on the `String`
type which allow bypassing utf-8 checks. These have all
been deprecated in favor of calling `.as_mut_vec()` and
then operating directly on the vector returned. These
methods were deprecated because naming them with relation
to other methods was difficult to rationalize and it's
arguably more composable to call .as_mut_vec().
* String::as_mut_bytes - See push_bytes
* String::push_byte - See push_bytes
* String::pop_byte - See push_bytes
* String::shift_byte - See push_bytes
# Reservation methods
This commit does not yet touch the methods for reserving bytes. The methods on
Vec have also not yet been modified. These methods are discussed in the upcoming
[Collections reform RFC][1]
[1]: https://github.com/aturon/rfcs/blob/collections-conventions/active/0000-collections-conventions.md#implicit-growth
2014-09-22 07:12:10 -07:00
|
|
|
|
/// ```
|
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-04 21:17:19 -05:00
|
|
|
|
pub fn capacity(&self) -> usize {
|
collections: Stabilize String
# Rationale
When dealing with strings, many functions deal with either a `char` (unicode
codepoint) or a byte (utf-8 encoding related). There is often an inconsistent
way in which methods are referred to as to whether they contain "byte", "char",
or nothing in their name. There are also issues open to rename *all* methods to
reflect that they operate on utf8 encodings or bytes (e.g. utf8_len() or
byte_len()).
The current state of String seems to largely be what is desired, so this PR
proposes the following rationale for methods dealing with bytes or characters:
> When constructing a string, the input encoding *must* be mentioned (e.g.
> from_utf8). This makes it clear what exactly the input type is expected to be
> in terms of encoding.
>
> When a method operates on anything related to an *index* within the string
> such as length, capacity, position, etc, the method *implicitly* operates on
> bytes. It is an understood fact that String is a utf-8 encoded string, and
> burdening all methods with "bytes" would be redundant.
>
> When a method operates on the *contents* of a string, such as push() or pop(),
> then "char" is the default type. A String can loosely be thought of as being a
> collection of unicode codepoints, but not all collection-related operations
> make sense because some can be woefully inefficient.
# Method stabilization
The following methods have been marked #[stable]
* The String type itself
* String::new
* String::with_capacity
* String::from_utf16_lossy
* String::into_bytes
* String::as_bytes
* String::len
* String::clear
* String::as_slice
The following methods have been marked #[unstable]
* String::from_utf8 - The error type in the returned `Result` may change to
provide a nicer message when it's `unwrap()`'d
* String::from_utf8_lossy - The returned `MaybeOwned` type still needs
stabilization
* String::from_utf16 - The return type may change to become a `Result` which
includes more contextual information like where the error
occurred.
* String::from_chars - This is equivalent to iter().collect(), but currently not
as ergonomic.
* String::from_char - This method is the equivalent of Vec::from_elem, and has
been marked #[unstable] becuase it can be seen as a
duplicate of iterator-based functionality as well as
possibly being renamed.
* String::push_str - This *can* be emulated with .extend(foo.chars()), but is
less efficient because of decoding/encoding. Due to the
desire to minimize API surface this may be able to be
removed in the future for something possibly generic with
no loss in performance.
* String::grow - This is a duplicate of iterator-based functionality, which may
become more ergonomic in the future.
* String::capacity - This function was just added.
* String::push - This function was just added.
* String::pop - This function was just added.
* String::truncate - The failure conventions around String methods and byte
indices isn't totally clear at this time, so the failure
semantics and return value of this method are subject to
change.
* String::as_mut_vec - the naming of this method may change.
* string::raw::* - these functions are all waiting on [an RFC][2]
[2]: https://github.com/rust-lang/rfcs/pull/240
The following method have been marked #[experimental]
* String::from_str - This function only exists as it's more efficient than
to_string(), but having a less ergonomic function for
performance reasons isn't the greatest reason to keep it
around. Like Vec::push_all, this has been marked
experimental for now.
The following methods have been #[deprecated]
* String::append - This method has been deprecated to remain consistent with the
deprecation of Vec::append. While convenient, it is one of
the only functional-style apis on String, and requires more
though as to whether it belongs as a first-class method or
now (and how it relates to other collections).
* String::from_byte - This is fairly rare functionality and can be emulated with
str::from_utf8 plus an assert plus a call to to_string().
Additionally, String::from_char could possibly be used.
* String::byte_capacity - Renamed to String::capacity due to the rationale
above.
* String::push_char - Renamed to String::push due to the rationale above.
* String::pop_char - Renamed to String::pop due to the rationale above.
* String::push_bytes - There are a number of `unsafe` functions on the `String`
type which allow bypassing utf-8 checks. These have all
been deprecated in favor of calling `.as_mut_vec()` and
then operating directly on the vector returned. These
methods were deprecated because naming them with relation
to other methods was difficult to rationalize and it's
arguably more composable to call .as_mut_vec().
* String::as_mut_bytes - See push_bytes
* String::push_byte - See push_bytes
* String::pop_byte - See push_bytes
* String::shift_byte - See push_bytes
# Reservation methods
This commit does not yet touch the methods for reserving bytes. The methods on
Vec have also not yet been modified. These methods are discussed in the upcoming
[Collections reform RFC][1]
[1]: https://github.com/aturon/rfcs/blob/collections-conventions/active/0000-collections-conventions.md#implicit-growth
2014-09-22 07:12:10 -07:00
|
|
|
|
self.vec.capacity()
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Ensures that this `String`'s capacity is at least `additional` bytes
|
|
|
|
|
/// larger than its length.
|
|
|
|
|
///
|
|
|
|
|
/// The capacity may be increased by more than `additional` bytes if it
|
|
|
|
|
/// chooses, to prevent frequent reallocations.
|
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// If you do not want this "at least" behavior, see the [`reserve_exact`]
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// method.
|
|
|
|
|
///
|
2014-11-06 12:24:47 -05:00
|
|
|
|
/// # Panics
|
|
|
|
|
///
|
2017-08-18 17:17:46 +02:00
|
|
|
|
/// Panics if the new capacity overflows [`usize`].
|
|
|
|
|
///
|
|
|
|
|
/// [`reserve_exact`]: struct.String.html#method.reserve_exact
|
|
|
|
|
/// [`usize`]: ../../std/primitive.usize.html
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
|
|
|
|
/// let mut s = String::new();
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// s.reserve(10);
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2014-09-22 08:28:35 -07:00
|
|
|
|
/// assert!(s.capacity() >= 10);
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
|
|
|
|
/// This may not actually increase the capacity:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let mut s = String::with_capacity(10);
|
|
|
|
|
/// s.push('a');
|
|
|
|
|
/// s.push('b');
|
|
|
|
|
///
|
|
|
|
|
/// // s now has a length of 2 and a capacity of 10
|
|
|
|
|
/// assert_eq!(2, s.len());
|
|
|
|
|
/// assert_eq!(10, s.capacity());
|
|
|
|
|
///
|
|
|
|
|
/// // Since we already have an extra 8 capacity, calling this...
|
|
|
|
|
/// s.reserve(8);
|
|
|
|
|
///
|
|
|
|
|
/// // ... doesn't actually increase.
|
|
|
|
|
/// assert_eq!(10, s.capacity());
|
|
|
|
|
/// ```
|
2014-04-02 16:54:22 -07:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-04 21:17:19 -05:00
|
|
|
|
pub fn reserve(&mut self, additional: usize) {
|
2014-11-06 12:24:47 -05:00
|
|
|
|
self.vec.reserve(additional)
|
2014-04-02 16:54:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Ensures that this `String`'s capacity is `additional` bytes
|
|
|
|
|
/// larger than its length.
|
2014-11-06 12:24:47 -05:00
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// Consider using the [`reserve`] method unless you absolutely know
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// better than the allocator.
|
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`reserve`]: #method.reserve
|
2014-11-06 12:24:47 -05:00
|
|
|
|
///
|
|
|
|
|
/// # Panics
|
|
|
|
|
///
|
2015-02-04 21:17:19 -05:00
|
|
|
|
/// Panics if the new capacity overflows `usize`.
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
|
|
|
|
/// let mut s = String::new();
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2015-05-16 20:59:20 -03:00
|
|
|
|
/// s.reserve_exact(10);
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2014-11-06 12:24:47 -05:00
|
|
|
|
/// assert!(s.capacity() >= 10);
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
|
|
|
|
/// This may not actually increase the capacity:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let mut s = String::with_capacity(10);
|
|
|
|
|
/// s.push('a');
|
|
|
|
|
/// s.push('b');
|
|
|
|
|
///
|
|
|
|
|
/// // s now has a length of 2 and a capacity of 10
|
|
|
|
|
/// assert_eq!(2, s.len());
|
|
|
|
|
/// assert_eq!(10, s.capacity());
|
|
|
|
|
///
|
|
|
|
|
/// // Since we already have an extra 8 capacity, calling this...
|
|
|
|
|
/// s.reserve_exact(8);
|
|
|
|
|
///
|
|
|
|
|
/// // ... doesn't actually increase.
|
|
|
|
|
/// assert_eq!(10, s.capacity());
|
|
|
|
|
/// ```
|
2014-04-02 16:54:22 -07:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-04 21:17:19 -05:00
|
|
|
|
pub fn reserve_exact(&mut self, additional: usize) {
|
2014-11-06 12:24:47 -05:00
|
|
|
|
self.vec.reserve_exact(additional)
|
2014-04-02 16:54:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
2018-03-08 14:36:43 +00:00
|
|
|
|
/// Tries to reserve capacity for at least `additional` more elements to be inserted
|
|
|
|
|
/// in the given `String`. The collection may reserve more space to avoid
|
|
|
|
|
/// frequent reallocations. After calling `reserve`, capacity will be
|
|
|
|
|
/// greater than or equal to `self.len() + additional`. Does nothing if
|
|
|
|
|
/// capacity is already sufficient.
|
|
|
|
|
///
|
|
|
|
|
/// # Errors
|
|
|
|
|
///
|
|
|
|
|
/// If the capacity overflows, or the allocator reports a failure, then an error
|
|
|
|
|
/// is returned.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// #![feature(try_reserve)]
|
|
|
|
|
/// use std::collections::CollectionAllocErr;
|
|
|
|
|
///
|
|
|
|
|
/// fn process_data(data: &str) -> Result<String, CollectionAllocErr> {
|
|
|
|
|
/// let mut output = String::new();
|
|
|
|
|
///
|
|
|
|
|
/// // Pre-reserve the memory, exiting if we can't
|
|
|
|
|
/// output.try_reserve(data.len())?;
|
|
|
|
|
///
|
|
|
|
|
/// // Now we know this can't OOM in the middle of our complex work
|
|
|
|
|
/// output.push_str(data);
|
|
|
|
|
///
|
|
|
|
|
/// Ok(output)
|
|
|
|
|
/// }
|
|
|
|
|
/// # process_data("rust").expect("why is the test harness OOMing on 4 bytes?");
|
|
|
|
|
/// ```
|
|
|
|
|
#[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
|
|
|
|
|
pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
|
|
|
|
|
self.vec.try_reserve(additional)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Tries to reserves the minimum capacity for exactly `additional` more elements to
|
|
|
|
|
/// be inserted in the given `String`. After calling `reserve_exact`,
|
|
|
|
|
/// capacity will be greater than or equal to `self.len() + additional`.
|
|
|
|
|
/// Does nothing if the capacity is already sufficient.
|
|
|
|
|
///
|
|
|
|
|
/// Note that the allocator may give the collection more space than it
|
|
|
|
|
/// requests. Therefore capacity can not be relied upon to be precisely
|
|
|
|
|
/// minimal. Prefer `reserve` if future insertions are expected.
|
|
|
|
|
///
|
|
|
|
|
/// # Errors
|
|
|
|
|
///
|
|
|
|
|
/// If the capacity overflows, or the allocator reports a failure, then an error
|
|
|
|
|
/// is returned.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// #![feature(try_reserve)]
|
|
|
|
|
/// use std::collections::CollectionAllocErr;
|
|
|
|
|
///
|
|
|
|
|
/// fn process_data(data: &str) -> Result<String, CollectionAllocErr> {
|
|
|
|
|
/// let mut output = String::new();
|
|
|
|
|
///
|
|
|
|
|
/// // Pre-reserve the memory, exiting if we can't
|
|
|
|
|
/// output.try_reserve(data.len())?;
|
|
|
|
|
///
|
|
|
|
|
/// // Now we know this can't OOM in the middle of our complex work
|
|
|
|
|
/// output.push_str(data);
|
|
|
|
|
///
|
|
|
|
|
/// Ok(output)
|
|
|
|
|
/// }
|
|
|
|
|
/// # process_data("rust").expect("why is the test harness OOMing on 4 bytes?");
|
|
|
|
|
/// ```
|
|
|
|
|
#[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
|
|
|
|
|
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
|
|
|
|
|
self.vec.try_reserve_exact(additional)
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Shrinks the capacity of this `String` to match its length.
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2015-05-19 03:33:17 +02:00
|
|
|
|
/// let mut s = String::from("foo");
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// s.reserve(100);
|
2014-09-22 08:28:35 -07:00
|
|
|
|
/// assert!(s.capacity() >= 100);
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// s.shrink_to_fit();
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// assert_eq!(3, s.capacity());
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2014-04-02 16:54:22 -07:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-04-02 16:54:22 -07:00
|
|
|
|
pub fn shrink_to_fit(&mut self) {
|
|
|
|
|
self.vec.shrink_to_fit()
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-26 23:24:31 +01:00
|
|
|
|
/// Shrinks the capacity of this `String` with a lower bound.
|
|
|
|
|
///
|
|
|
|
|
/// The capacity will remain at least as large as both the length
|
|
|
|
|
/// and the supplied value.
|
|
|
|
|
///
|
|
|
|
|
/// Panics if the current capacity is smaller than the supplied
|
|
|
|
|
/// minimum capacity.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// #![feature(shrink_to)]
|
|
|
|
|
/// let mut s = String::from("foo");
|
|
|
|
|
///
|
|
|
|
|
/// s.reserve(100);
|
|
|
|
|
/// assert!(s.capacity() >= 100);
|
|
|
|
|
///
|
|
|
|
|
/// s.shrink_to(10);
|
|
|
|
|
/// assert!(s.capacity() >= 10);
|
|
|
|
|
/// s.shrink_to(0);
|
|
|
|
|
/// assert!(s.capacity() >= 3);
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline]
|
|
|
|
|
#[unstable(feature = "shrink_to", reason = "new API", issue="0")]
|
|
|
|
|
pub fn shrink_to(&mut self, min_capacity: usize) {
|
|
|
|
|
self.vec.shrink_to(min_capacity)
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-18 17:17:46 +02:00
|
|
|
|
/// Appends the given [`char`] to the end of this `String`.
|
|
|
|
|
///
|
|
|
|
|
/// [`char`]: ../../std/primitive.char.html
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2015-05-19 03:33:17 +02:00
|
|
|
|
/// let mut s = String::from("abc");
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
collections: Stabilize String
# Rationale
When dealing with strings, many functions deal with either a `char` (unicode
codepoint) or a byte (utf-8 encoding related). There is often an inconsistent
way in which methods are referred to as to whether they contain "byte", "char",
or nothing in their name. There are also issues open to rename *all* methods to
reflect that they operate on utf8 encodings or bytes (e.g. utf8_len() or
byte_len()).
The current state of String seems to largely be what is desired, so this PR
proposes the following rationale for methods dealing with bytes or characters:
> When constructing a string, the input encoding *must* be mentioned (e.g.
> from_utf8). This makes it clear what exactly the input type is expected to be
> in terms of encoding.
>
> When a method operates on anything related to an *index* within the string
> such as length, capacity, position, etc, the method *implicitly* operates on
> bytes. It is an understood fact that String is a utf-8 encoded string, and
> burdening all methods with "bytes" would be redundant.
>
> When a method operates on the *contents* of a string, such as push() or pop(),
> then "char" is the default type. A String can loosely be thought of as being a
> collection of unicode codepoints, but not all collection-related operations
> make sense because some can be woefully inefficient.
# Method stabilization
The following methods have been marked #[stable]
* The String type itself
* String::new
* String::with_capacity
* String::from_utf16_lossy
* String::into_bytes
* String::as_bytes
* String::len
* String::clear
* String::as_slice
The following methods have been marked #[unstable]
* String::from_utf8 - The error type in the returned `Result` may change to
provide a nicer message when it's `unwrap()`'d
* String::from_utf8_lossy - The returned `MaybeOwned` type still needs
stabilization
* String::from_utf16 - The return type may change to become a `Result` which
includes more contextual information like where the error
occurred.
* String::from_chars - This is equivalent to iter().collect(), but currently not
as ergonomic.
* String::from_char - This method is the equivalent of Vec::from_elem, and has
been marked #[unstable] becuase it can be seen as a
duplicate of iterator-based functionality as well as
possibly being renamed.
* String::push_str - This *can* be emulated with .extend(foo.chars()), but is
less efficient because of decoding/encoding. Due to the
desire to minimize API surface this may be able to be
removed in the future for something possibly generic with
no loss in performance.
* String::grow - This is a duplicate of iterator-based functionality, which may
become more ergonomic in the future.
* String::capacity - This function was just added.
* String::push - This function was just added.
* String::pop - This function was just added.
* String::truncate - The failure conventions around String methods and byte
indices isn't totally clear at this time, so the failure
semantics and return value of this method are subject to
change.
* String::as_mut_vec - the naming of this method may change.
* string::raw::* - these functions are all waiting on [an RFC][2]
[2]: https://github.com/rust-lang/rfcs/pull/240
The following method have been marked #[experimental]
* String::from_str - This function only exists as it's more efficient than
to_string(), but having a less ergonomic function for
performance reasons isn't the greatest reason to keep it
around. Like Vec::push_all, this has been marked
experimental for now.
The following methods have been #[deprecated]
* String::append - This method has been deprecated to remain consistent with the
deprecation of Vec::append. While convenient, it is one of
the only functional-style apis on String, and requires more
though as to whether it belongs as a first-class method or
now (and how it relates to other collections).
* String::from_byte - This is fairly rare functionality and can be emulated with
str::from_utf8 plus an assert plus a call to to_string().
Additionally, String::from_char could possibly be used.
* String::byte_capacity - Renamed to String::capacity due to the rationale
above.
* String::push_char - Renamed to String::push due to the rationale above.
* String::pop_char - Renamed to String::pop due to the rationale above.
* String::push_bytes - There are a number of `unsafe` functions on the `String`
type which allow bypassing utf-8 checks. These have all
been deprecated in favor of calling `.as_mut_vec()` and
then operating directly on the vector returned. These
methods were deprecated because naming them with relation
to other methods was difficult to rationalize and it's
arguably more composable to call .as_mut_vec().
* String::as_mut_bytes - See push_bytes
* String::push_byte - See push_bytes
* String::pop_byte - See push_bytes
* String::shift_byte - See push_bytes
# Reservation methods
This commit does not yet touch the methods for reserving bytes. The methods on
Vec have also not yet been modified. These methods are discussed in the upcoming
[Collections reform RFC][1]
[1]: https://github.com/aturon/rfcs/blob/collections-conventions/active/0000-collections-conventions.md#implicit-growth
2014-09-22 07:12:10 -07:00
|
|
|
|
/// s.push('1');
|
|
|
|
|
/// s.push('2');
|
|
|
|
|
/// s.push('3');
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
|
|
|
|
/// assert_eq!("abc123", s);
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2014-04-02 16:54:22 -07:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
collections: Stabilize String
# Rationale
When dealing with strings, many functions deal with either a `char` (unicode
codepoint) or a byte (utf-8 encoding related). There is often an inconsistent
way in which methods are referred to as to whether they contain "byte", "char",
or nothing in their name. There are also issues open to rename *all* methods to
reflect that they operate on utf8 encodings or bytes (e.g. utf8_len() or
byte_len()).
The current state of String seems to largely be what is desired, so this PR
proposes the following rationale for methods dealing with bytes or characters:
> When constructing a string, the input encoding *must* be mentioned (e.g.
> from_utf8). This makes it clear what exactly the input type is expected to be
> in terms of encoding.
>
> When a method operates on anything related to an *index* within the string
> such as length, capacity, position, etc, the method *implicitly* operates on
> bytes. It is an understood fact that String is a utf-8 encoded string, and
> burdening all methods with "bytes" would be redundant.
>
> When a method operates on the *contents* of a string, such as push() or pop(),
> then "char" is the default type. A String can loosely be thought of as being a
> collection of unicode codepoints, but not all collection-related operations
> make sense because some can be woefully inefficient.
# Method stabilization
The following methods have been marked #[stable]
* The String type itself
* String::new
* String::with_capacity
* String::from_utf16_lossy
* String::into_bytes
* String::as_bytes
* String::len
* String::clear
* String::as_slice
The following methods have been marked #[unstable]
* String::from_utf8 - The error type in the returned `Result` may change to
provide a nicer message when it's `unwrap()`'d
* String::from_utf8_lossy - The returned `MaybeOwned` type still needs
stabilization
* String::from_utf16 - The return type may change to become a `Result` which
includes more contextual information like where the error
occurred.
* String::from_chars - This is equivalent to iter().collect(), but currently not
as ergonomic.
* String::from_char - This method is the equivalent of Vec::from_elem, and has
been marked #[unstable] becuase it can be seen as a
duplicate of iterator-based functionality as well as
possibly being renamed.
* String::push_str - This *can* be emulated with .extend(foo.chars()), but is
less efficient because of decoding/encoding. Due to the
desire to minimize API surface this may be able to be
removed in the future for something possibly generic with
no loss in performance.
* String::grow - This is a duplicate of iterator-based functionality, which may
become more ergonomic in the future.
* String::capacity - This function was just added.
* String::push - This function was just added.
* String::pop - This function was just added.
* String::truncate - The failure conventions around String methods and byte
indices isn't totally clear at this time, so the failure
semantics and return value of this method are subject to
change.
* String::as_mut_vec - the naming of this method may change.
* string::raw::* - these functions are all waiting on [an RFC][2]
[2]: https://github.com/rust-lang/rfcs/pull/240
The following method have been marked #[experimental]
* String::from_str - This function only exists as it's more efficient than
to_string(), but having a less ergonomic function for
performance reasons isn't the greatest reason to keep it
around. Like Vec::push_all, this has been marked
experimental for now.
The following methods have been #[deprecated]
* String::append - This method has been deprecated to remain consistent with the
deprecation of Vec::append. While convenient, it is one of
the only functional-style apis on String, and requires more
though as to whether it belongs as a first-class method or
now (and how it relates to other collections).
* String::from_byte - This is fairly rare functionality and can be emulated with
str::from_utf8 plus an assert plus a call to to_string().
Additionally, String::from_char could possibly be used.
* String::byte_capacity - Renamed to String::capacity due to the rationale
above.
* String::push_char - Renamed to String::push due to the rationale above.
* String::pop_char - Renamed to String::pop due to the rationale above.
* String::push_bytes - There are a number of `unsafe` functions on the `String`
type which allow bypassing utf-8 checks. These have all
been deprecated in favor of calling `.as_mut_vec()` and
then operating directly on the vector returned. These
methods were deprecated because naming them with relation
to other methods was difficult to rationalize and it's
arguably more composable to call .as_mut_vec().
* String::as_mut_bytes - See push_bytes
* String::push_byte - See push_bytes
* String::pop_byte - See push_bytes
* String::shift_byte - See push_bytes
# Reservation methods
This commit does not yet touch the methods for reserving bytes. The methods on
Vec have also not yet been modified. These methods are discussed in the upcoming
[Collections reform RFC][1]
[1]: https://github.com/aturon/rfcs/blob/collections-conventions/active/0000-collections-conventions.md#implicit-growth
2014-09-22 07:12:10 -07:00
|
|
|
|
pub fn push(&mut self, ch: char) {
|
2015-06-10 02:03:56 +02:00
|
|
|
|
match ch.len_utf8() {
|
|
|
|
|
1 => self.vec.push(ch as u8),
|
2016-12-20 09:54:00 +05:30
|
|
|
|
_ => self.vec.extend_from_slice(ch.encode_utf8(&mut [0; 4]).as_bytes()),
|
2014-04-02 16:54:22 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Returns a byte slice of this `String`'s contents.
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2017-03-03 01:24:19 -05:00
|
|
|
|
/// The inverse of this method is [`from_utf8`].
|
|
|
|
|
///
|
|
|
|
|
/// [`from_utf8`]: #method.from_utf8
|
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2015-05-19 03:33:17 +02:00
|
|
|
|
/// let s = String::from("hello");
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(&[104, 101, 108, 108, 111], s.as_bytes());
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2014-04-02 16:54:22 -07:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-05 13:48:20 -05:00
|
|
|
|
pub fn as_bytes(&self) -> &[u8] {
|
2015-02-01 21:53:25 -05:00
|
|
|
|
&self.vec
|
2014-04-02 16:54:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Shortens this `String` to the specified length.
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2016-04-14 16:56:59 -07:00
|
|
|
|
/// If `new_len` is greater than the string's current length, this has no
|
|
|
|
|
/// effect.
|
|
|
|
|
///
|
2017-02-11 20:29:29 +11:00
|
|
|
|
/// Note that this method has no effect on the allocated capacity
|
|
|
|
|
/// of the string
|
|
|
|
|
///
|
2014-11-12 03:36:09 +09:00
|
|
|
|
/// # Panics
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2016-04-14 16:56:59 -07:00
|
|
|
|
/// Panics if `new_len` does not lie on a [`char`] boundary.
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2016-03-07 23:55:52 -08:00
|
|
|
|
/// [`char`]: ../../std/primitive.char.html
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2015-05-19 03:33:17 +02:00
|
|
|
|
/// let mut s = String::from("hello");
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// s.truncate(2);
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
|
|
|
|
/// assert_eq!("he", s);
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2014-04-02 16:54:22 -07:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-04 21:17:19 -05:00
|
|
|
|
pub fn truncate(&mut self, new_len: usize) {
|
2016-04-14 16:56:59 -07:00
|
|
|
|
if new_len <= self.len() {
|
|
|
|
|
assert!(self.is_char_boundary(new_len));
|
|
|
|
|
self.vec.truncate(new_len)
|
|
|
|
|
}
|
2014-04-02 16:54:22 -07:00
|
|
|
|
}
|
|
|
|
|
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// Removes the last character from the string buffer and returns it.
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2017-08-18 17:17:46 +02:00
|
|
|
|
/// Returns [`None`] if this `String` is empty.
|
|
|
|
|
///
|
|
|
|
|
/// [`None`]: ../../std/option/enum.Option.html#variant.None
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2015-05-19 03:33:17 +02:00
|
|
|
|
/// let mut s = String::from("foo");
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
collections: Stabilize String
# Rationale
When dealing with strings, many functions deal with either a `char` (unicode
codepoint) or a byte (utf-8 encoding related). There is often an inconsistent
way in which methods are referred to as to whether they contain "byte", "char",
or nothing in their name. There are also issues open to rename *all* methods to
reflect that they operate on utf8 encodings or bytes (e.g. utf8_len() or
byte_len()).
The current state of String seems to largely be what is desired, so this PR
proposes the following rationale for methods dealing with bytes or characters:
> When constructing a string, the input encoding *must* be mentioned (e.g.
> from_utf8). This makes it clear what exactly the input type is expected to be
> in terms of encoding.
>
> When a method operates on anything related to an *index* within the string
> such as length, capacity, position, etc, the method *implicitly* operates on
> bytes. It is an understood fact that String is a utf-8 encoded string, and
> burdening all methods with "bytes" would be redundant.
>
> When a method operates on the *contents* of a string, such as push() or pop(),
> then "char" is the default type. A String can loosely be thought of as being a
> collection of unicode codepoints, but not all collection-related operations
> make sense because some can be woefully inefficient.
# Method stabilization
The following methods have been marked #[stable]
* The String type itself
* String::new
* String::with_capacity
* String::from_utf16_lossy
* String::into_bytes
* String::as_bytes
* String::len
* String::clear
* String::as_slice
The following methods have been marked #[unstable]
* String::from_utf8 - The error type in the returned `Result` may change to
provide a nicer message when it's `unwrap()`'d
* String::from_utf8_lossy - The returned `MaybeOwned` type still needs
stabilization
* String::from_utf16 - The return type may change to become a `Result` which
includes more contextual information like where the error
occurred.
* String::from_chars - This is equivalent to iter().collect(), but currently not
as ergonomic.
* String::from_char - This method is the equivalent of Vec::from_elem, and has
been marked #[unstable] becuase it can be seen as a
duplicate of iterator-based functionality as well as
possibly being renamed.
* String::push_str - This *can* be emulated with .extend(foo.chars()), but is
less efficient because of decoding/encoding. Due to the
desire to minimize API surface this may be able to be
removed in the future for something possibly generic with
no loss in performance.
* String::grow - This is a duplicate of iterator-based functionality, which may
become more ergonomic in the future.
* String::capacity - This function was just added.
* String::push - This function was just added.
* String::pop - This function was just added.
* String::truncate - The failure conventions around String methods and byte
indices isn't totally clear at this time, so the failure
semantics and return value of this method are subject to
change.
* String::as_mut_vec - the naming of this method may change.
* string::raw::* - these functions are all waiting on [an RFC][2]
[2]: https://github.com/rust-lang/rfcs/pull/240
The following method have been marked #[experimental]
* String::from_str - This function only exists as it's more efficient than
to_string(), but having a less ergonomic function for
performance reasons isn't the greatest reason to keep it
around. Like Vec::push_all, this has been marked
experimental for now.
The following methods have been #[deprecated]
* String::append - This method has been deprecated to remain consistent with the
deprecation of Vec::append. While convenient, it is one of
the only functional-style apis on String, and requires more
though as to whether it belongs as a first-class method or
now (and how it relates to other collections).
* String::from_byte - This is fairly rare functionality and can be emulated with
str::from_utf8 plus an assert plus a call to to_string().
Additionally, String::from_char could possibly be used.
* String::byte_capacity - Renamed to String::capacity due to the rationale
above.
* String::push_char - Renamed to String::push due to the rationale above.
* String::pop_char - Renamed to String::pop due to the rationale above.
* String::push_bytes - There are a number of `unsafe` functions on the `String`
type which allow bypassing utf-8 checks. These have all
been deprecated in favor of calling `.as_mut_vec()` and
then operating directly on the vector returned. These
methods were deprecated because naming them with relation
to other methods was difficult to rationalize and it's
arguably more composable to call .as_mut_vec().
* String::as_mut_bytes - See push_bytes
* String::push_byte - See push_bytes
* String::pop_byte - See push_bytes
* String::shift_byte - See push_bytes
# Reservation methods
This commit does not yet touch the methods for reserving bytes. The methods on
Vec have also not yet been modified. These methods are discussed in the upcoming
[Collections reform RFC][1]
[1]: https://github.com/aturon/rfcs/blob/collections-conventions/active/0000-collections-conventions.md#implicit-growth
2014-09-22 07:12:10 -07:00
|
|
|
|
/// assert_eq!(s.pop(), Some('o'));
|
|
|
|
|
/// assert_eq!(s.pop(), Some('o'));
|
|
|
|
|
/// assert_eq!(s.pop(), Some('f'));
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
collections: Stabilize String
# Rationale
When dealing with strings, many functions deal with either a `char` (unicode
codepoint) or a byte (utf-8 encoding related). There is often an inconsistent
way in which methods are referred to as to whether they contain "byte", "char",
or nothing in their name. There are also issues open to rename *all* methods to
reflect that they operate on utf8 encodings or bytes (e.g. utf8_len() or
byte_len()).
The current state of String seems to largely be what is desired, so this PR
proposes the following rationale for methods dealing with bytes or characters:
> When constructing a string, the input encoding *must* be mentioned (e.g.
> from_utf8). This makes it clear what exactly the input type is expected to be
> in terms of encoding.
>
> When a method operates on anything related to an *index* within the string
> such as length, capacity, position, etc, the method *implicitly* operates on
> bytes. It is an understood fact that String is a utf-8 encoded string, and
> burdening all methods with "bytes" would be redundant.
>
> When a method operates on the *contents* of a string, such as push() or pop(),
> then "char" is the default type. A String can loosely be thought of as being a
> collection of unicode codepoints, but not all collection-related operations
> make sense because some can be woefully inefficient.
# Method stabilization
The following methods have been marked #[stable]
* The String type itself
* String::new
* String::with_capacity
* String::from_utf16_lossy
* String::into_bytes
* String::as_bytes
* String::len
* String::clear
* String::as_slice
The following methods have been marked #[unstable]
* String::from_utf8 - The error type in the returned `Result` may change to
provide a nicer message when it's `unwrap()`'d
* String::from_utf8_lossy - The returned `MaybeOwned` type still needs
stabilization
* String::from_utf16 - The return type may change to become a `Result` which
includes more contextual information like where the error
occurred.
* String::from_chars - This is equivalent to iter().collect(), but currently not
as ergonomic.
* String::from_char - This method is the equivalent of Vec::from_elem, and has
been marked #[unstable] becuase it can be seen as a
duplicate of iterator-based functionality as well as
possibly being renamed.
* String::push_str - This *can* be emulated with .extend(foo.chars()), but is
less efficient because of decoding/encoding. Due to the
desire to minimize API surface this may be able to be
removed in the future for something possibly generic with
no loss in performance.
* String::grow - This is a duplicate of iterator-based functionality, which may
become more ergonomic in the future.
* String::capacity - This function was just added.
* String::push - This function was just added.
* String::pop - This function was just added.
* String::truncate - The failure conventions around String methods and byte
indices isn't totally clear at this time, so the failure
semantics and return value of this method are subject to
change.
* String::as_mut_vec - the naming of this method may change.
* string::raw::* - these functions are all waiting on [an RFC][2]
[2]: https://github.com/rust-lang/rfcs/pull/240
The following method have been marked #[experimental]
* String::from_str - This function only exists as it's more efficient than
to_string(), but having a less ergonomic function for
performance reasons isn't the greatest reason to keep it
around. Like Vec::push_all, this has been marked
experimental for now.
The following methods have been #[deprecated]
* String::append - This method has been deprecated to remain consistent with the
deprecation of Vec::append. While convenient, it is one of
the only functional-style apis on String, and requires more
though as to whether it belongs as a first-class method or
now (and how it relates to other collections).
* String::from_byte - This is fairly rare functionality and can be emulated with
str::from_utf8 plus an assert plus a call to to_string().
Additionally, String::from_char could possibly be used.
* String::byte_capacity - Renamed to String::capacity due to the rationale
above.
* String::push_char - Renamed to String::push due to the rationale above.
* String::pop_char - Renamed to String::pop due to the rationale above.
* String::push_bytes - There are a number of `unsafe` functions on the `String`
type which allow bypassing utf-8 checks. These have all
been deprecated in favor of calling `.as_mut_vec()` and
then operating directly on the vector returned. These
methods were deprecated because naming them with relation
to other methods was difficult to rationalize and it's
arguably more composable to call .as_mut_vec().
* String::as_mut_bytes - See push_bytes
* String::push_byte - See push_bytes
* String::pop_byte - See push_bytes
* String::shift_byte - See push_bytes
# Reservation methods
This commit does not yet touch the methods for reserving bytes. The methods on
Vec have also not yet been modified. These methods are discussed in the upcoming
[Collections reform RFC][1]
[1]: https://github.com/aturon/rfcs/blob/collections-conventions/active/0000-collections-conventions.md#implicit-growth
2014-09-22 07:12:10 -07:00
|
|
|
|
/// assert_eq!(s.pop(), None);
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2014-05-08 21:42:40 +01:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
collections: Stabilize String
# Rationale
When dealing with strings, many functions deal with either a `char` (unicode
codepoint) or a byte (utf-8 encoding related). There is often an inconsistent
way in which methods are referred to as to whether they contain "byte", "char",
or nothing in their name. There are also issues open to rename *all* methods to
reflect that they operate on utf8 encodings or bytes (e.g. utf8_len() or
byte_len()).
The current state of String seems to largely be what is desired, so this PR
proposes the following rationale for methods dealing with bytes or characters:
> When constructing a string, the input encoding *must* be mentioned (e.g.
> from_utf8). This makes it clear what exactly the input type is expected to be
> in terms of encoding.
>
> When a method operates on anything related to an *index* within the string
> such as length, capacity, position, etc, the method *implicitly* operates on
> bytes. It is an understood fact that String is a utf-8 encoded string, and
> burdening all methods with "bytes" would be redundant.
>
> When a method operates on the *contents* of a string, such as push() or pop(),
> then "char" is the default type. A String can loosely be thought of as being a
> collection of unicode codepoints, but not all collection-related operations
> make sense because some can be woefully inefficient.
# Method stabilization
The following methods have been marked #[stable]
* The String type itself
* String::new
* String::with_capacity
* String::from_utf16_lossy
* String::into_bytes
* String::as_bytes
* String::len
* String::clear
* String::as_slice
The following methods have been marked #[unstable]
* String::from_utf8 - The error type in the returned `Result` may change to
provide a nicer message when it's `unwrap()`'d
* String::from_utf8_lossy - The returned `MaybeOwned` type still needs
stabilization
* String::from_utf16 - The return type may change to become a `Result` which
includes more contextual information like where the error
occurred.
* String::from_chars - This is equivalent to iter().collect(), but currently not
as ergonomic.
* String::from_char - This method is the equivalent of Vec::from_elem, and has
been marked #[unstable] becuase it can be seen as a
duplicate of iterator-based functionality as well as
possibly being renamed.
* String::push_str - This *can* be emulated with .extend(foo.chars()), but is
less efficient because of decoding/encoding. Due to the
desire to minimize API surface this may be able to be
removed in the future for something possibly generic with
no loss in performance.
* String::grow - This is a duplicate of iterator-based functionality, which may
become more ergonomic in the future.
* String::capacity - This function was just added.
* String::push - This function was just added.
* String::pop - This function was just added.
* String::truncate - The failure conventions around String methods and byte
indices isn't totally clear at this time, so the failure
semantics and return value of this method are subject to
change.
* String::as_mut_vec - the naming of this method may change.
* string::raw::* - these functions are all waiting on [an RFC][2]
[2]: https://github.com/rust-lang/rfcs/pull/240
The following method have been marked #[experimental]
* String::from_str - This function only exists as it's more efficient than
to_string(), but having a less ergonomic function for
performance reasons isn't the greatest reason to keep it
around. Like Vec::push_all, this has been marked
experimental for now.
The following methods have been #[deprecated]
* String::append - This method has been deprecated to remain consistent with the
deprecation of Vec::append. While convenient, it is one of
the only functional-style apis on String, and requires more
though as to whether it belongs as a first-class method or
now (and how it relates to other collections).
* String::from_byte - This is fairly rare functionality and can be emulated with
str::from_utf8 plus an assert plus a call to to_string().
Additionally, String::from_char could possibly be used.
* String::byte_capacity - Renamed to String::capacity due to the rationale
above.
* String::push_char - Renamed to String::push due to the rationale above.
* String::pop_char - Renamed to String::pop due to the rationale above.
* String::push_bytes - There are a number of `unsafe` functions on the `String`
type which allow bypassing utf-8 checks. These have all
been deprecated in favor of calling `.as_mut_vec()` and
then operating directly on the vector returned. These
methods were deprecated because naming them with relation
to other methods was difficult to rationalize and it's
arguably more composable to call .as_mut_vec().
* String::as_mut_bytes - See push_bytes
* String::push_byte - See push_bytes
* String::pop_byte - See push_bytes
* String::shift_byte - See push_bytes
# Reservation methods
This commit does not yet touch the methods for reserving bytes. The methods on
Vec have also not yet been modified. These methods are discussed in the upcoming
[Collections reform RFC][1]
[1]: https://github.com/aturon/rfcs/blob/collections-conventions/active/0000-collections-conventions.md#implicit-growth
2014-09-22 07:12:10 -07:00
|
|
|
|
pub fn pop(&mut self) -> Option<char> {
|
2017-12-08 17:32:04 -08:00
|
|
|
|
let ch = self.chars().rev().next()?;
|
2016-04-07 10:42:53 -07:00
|
|
|
|
let newlen = self.len() - ch.len_utf8();
|
2014-05-08 21:42:40 +01:00
|
|
|
|
unsafe {
|
2016-04-07 10:42:53 -07:00
|
|
|
|
self.vec.set_len(newlen);
|
2014-05-08 21:42:40 +01:00
|
|
|
|
}
|
|
|
|
|
Some(ch)
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-18 17:17:46 +02:00
|
|
|
|
/// Removes a [`char`] from this `String` at a byte position and returns it.
|
2014-05-08 21:42:40 +01:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// This is an `O(n)` operation, as it requires copying every element in the
|
2014-09-22 08:24:14 -07:00
|
|
|
|
/// buffer.
|
|
|
|
|
///
|
2014-10-09 15:17:22 -04:00
|
|
|
|
/// # Panics
|
2014-09-22 08:24:14 -07:00
|
|
|
|
///
|
2016-01-02 22:36:50 +01:00
|
|
|
|
/// Panics if `idx` is larger than or equal to the `String`'s length,
|
|
|
|
|
/// or if it does not lie on a [`char`] boundary.
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2016-03-07 23:55:52 -08:00
|
|
|
|
/// [`char`]: ../../std/primitive.char.html
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2015-05-19 03:33:17 +02:00
|
|
|
|
/// let mut s = String::from("foo");
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2014-12-28 10:29:56 -08:00
|
|
|
|
/// assert_eq!(s.remove(0), 'f');
|
|
|
|
|
/// assert_eq!(s.remove(1), 'o');
|
|
|
|
|
/// assert_eq!(s.remove(0), 'o');
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2015-01-10 11:07:14 +01:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-04 21:17:19 -05:00
|
|
|
|
pub fn remove(&mut self, idx: usize) -> char {
|
2016-04-07 10:42:53 -07:00
|
|
|
|
let ch = match self[idx..].chars().next() {
|
|
|
|
|
Some(ch) => ch,
|
|
|
|
|
None => panic!("cannot remove a char from the end of a string"),
|
|
|
|
|
};
|
2014-04-02 16:54:22 -07:00
|
|
|
|
|
2015-03-10 16:29:02 -07:00
|
|
|
|
let next = idx + ch.len_utf8();
|
2016-04-07 10:42:53 -07:00
|
|
|
|
let len = self.len();
|
2014-05-08 21:42:40 +01:00
|
|
|
|
unsafe {
|
2015-03-27 11:12:28 -07:00
|
|
|
|
ptr::copy(self.vec.as_ptr().offset(next as isize),
|
|
|
|
|
self.vec.as_mut_ptr().offset(idx as isize),
|
2015-02-23 11:39:16 -08:00
|
|
|
|
len - next);
|
2014-09-22 08:24:14 -07:00
|
|
|
|
self.vec.set_len(len - (next - idx));
|
2014-05-08 21:42:40 +01:00
|
|
|
|
}
|
2014-12-28 10:29:56 -08:00
|
|
|
|
ch
|
2014-04-02 16:54:22 -07:00
|
|
|
|
}
|
2014-04-12 22:44:31 +10:00
|
|
|
|
|
2017-07-26 15:09:32 -07:00
|
|
|
|
/// Retains only the characters specified by the predicate.
|
|
|
|
|
///
|
|
|
|
|
/// In other words, remove all characters `c` such that `f(c)` returns `false`.
|
|
|
|
|
/// This method operates in place and preserves the order of the retained
|
|
|
|
|
/// characters.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let mut s = String::from("f_o_ob_ar");
|
|
|
|
|
///
|
|
|
|
|
/// s.retain(|c| c != '_');
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(s, "foobar");
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline]
|
2018-03-21 10:47:03 -07:00
|
|
|
|
#[stable(feature = "string_retain", since = "1.26.0")]
|
2017-07-26 15:09:32 -07:00
|
|
|
|
pub fn retain<F>(&mut self, mut f: F)
|
|
|
|
|
where F: FnMut(char) -> bool
|
|
|
|
|
{
|
|
|
|
|
let len = self.len();
|
|
|
|
|
let mut del_bytes = 0;
|
|
|
|
|
let mut idx = 0;
|
|
|
|
|
|
|
|
|
|
while idx < len {
|
|
|
|
|
let ch = unsafe {
|
|
|
|
|
self.slice_unchecked(idx, len).chars().next().unwrap()
|
|
|
|
|
};
|
|
|
|
|
let ch_len = ch.len_utf8();
|
|
|
|
|
|
|
|
|
|
if !f(ch) {
|
|
|
|
|
del_bytes += ch_len;
|
|
|
|
|
} else if del_bytes > 0 {
|
|
|
|
|
unsafe {
|
|
|
|
|
ptr::copy(self.vec.as_ptr().offset(idx as isize),
|
|
|
|
|
self.vec.as_mut_ptr().offset((idx - del_bytes) as isize),
|
|
|
|
|
ch_len);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Point idx to the next char
|
|
|
|
|
idx += ch_len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if del_bytes > 0 {
|
|
|
|
|
unsafe { self.vec.set_len(len - del_bytes); }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Inserts a character into this `String` at a byte position.
|
2014-09-22 08:24:14 -07:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// This is an `O(n)` operation as it requires copying every element in the
|
2014-09-22 08:24:14 -07:00
|
|
|
|
/// buffer.
|
|
|
|
|
///
|
2014-10-09 15:17:22 -04:00
|
|
|
|
/// # Panics
|
2014-09-22 08:24:14 -07:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Panics if `idx` is larger than the `String`'s length, or if it does not
|
|
|
|
|
/// lie on a [`char`] boundary.
|
|
|
|
|
///
|
2016-03-07 23:55:52 -08:00
|
|
|
|
/// [`char`]: ../../std/primitive.char.html
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let mut s = String::with_capacity(3);
|
|
|
|
|
///
|
|
|
|
|
/// s.insert(0, 'f');
|
|
|
|
|
/// s.insert(1, 'o');
|
|
|
|
|
/// s.insert(2, 'o');
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!("foo", s);
|
|
|
|
|
/// ```
|
2015-01-10 11:07:14 +01:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-04 21:17:19 -05:00
|
|
|
|
pub fn insert(&mut self, idx: usize, ch: char) {
|
2014-11-27 11:45:50 -05:00
|
|
|
|
assert!(self.is_char_boundary(idx));
|
2016-09-08 13:54:39 +02:00
|
|
|
|
let mut bits = [0; 4];
|
|
|
|
|
let bits = ch.encode_utf8(&mut bits).as_bytes();
|
2016-07-11 15:06:28 -07:00
|
|
|
|
|
|
|
|
|
unsafe {
|
2016-09-08 13:54:39 +02:00
|
|
|
|
self.insert_bytes(idx, bits);
|
2016-07-11 15:06:28 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsafe fn insert_bytes(&mut self, idx: usize, bytes: &[u8]) {
|
|
|
|
|
let len = self.len();
|
|
|
|
|
let amt = bytes.len();
|
2016-03-11 11:01:46 -08:00
|
|
|
|
self.vec.reserve(amt);
|
2014-09-22 08:24:14 -07:00
|
|
|
|
|
2016-07-11 15:06:28 -07:00
|
|
|
|
ptr::copy(self.vec.as_ptr().offset(idx as isize),
|
|
|
|
|
self.vec.as_mut_ptr().offset((idx + amt) as isize),
|
|
|
|
|
len - idx);
|
|
|
|
|
ptr::copy(bytes.as_ptr(),
|
|
|
|
|
self.vec.as_mut_ptr().offset(idx as isize),
|
|
|
|
|
amt);
|
|
|
|
|
self.vec.set_len(len + amt);
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-11 20:41:04 +02:00
|
|
|
|
/// Inserts a string slice into this `String` at a byte position.
|
2016-07-11 15:06:28 -07:00
|
|
|
|
///
|
|
|
|
|
/// This is an `O(n)` operation as it requires copying every element in the
|
|
|
|
|
/// buffer.
|
|
|
|
|
///
|
|
|
|
|
/// # Panics
|
|
|
|
|
///
|
|
|
|
|
/// Panics if `idx` is larger than the `String`'s length, or if it does not
|
|
|
|
|
/// lie on a [`char`] boundary.
|
|
|
|
|
///
|
|
|
|
|
/// [`char`]: ../../std/primitive.char.html
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let mut s = String::from("bar");
|
|
|
|
|
///
|
|
|
|
|
/// s.insert_str(0, "foo");
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!("foobar", s);
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline]
|
2017-01-25 15:37:20 -08:00
|
|
|
|
#[stable(feature = "insert_str", since = "1.16.0")]
|
2016-07-11 15:06:28 -07:00
|
|
|
|
pub fn insert_str(&mut self, idx: usize, string: &str) {
|
|
|
|
|
assert!(self.is_char_boundary(idx));
|
|
|
|
|
|
2014-09-22 08:24:14 -07:00
|
|
|
|
unsafe {
|
2016-07-11 15:06:28 -07:00
|
|
|
|
self.insert_bytes(idx, string.as_bytes());
|
2014-09-22 08:24:14 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Returns a mutable reference to the contents of this `String`.
|
2014-04-12 22:44:31 +10:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// # Safety
|
|
|
|
|
///
|
|
|
|
|
/// This function is unsafe because it does not check that the bytes passed
|
|
|
|
|
/// to it are valid UTF-8. If this constraint is violated, it may cause
|
|
|
|
|
/// memory unsafety issues with future users of the `String`, as the rest of
|
|
|
|
|
/// the standard library assumes that `String`s are valid UTF-8.
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-07-27 12:40:39 +02:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2015-05-19 03:33:17 +02:00
|
|
|
|
/// let mut s = String::from("hello");
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// unsafe {
|
|
|
|
|
/// let vec = s.as_mut_vec();
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// assert_eq!(&[104, 101, 108, 108, 111][..], &vec[..]);
|
|
|
|
|
///
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// vec.reverse();
|
|
|
|
|
/// }
|
2015-03-07 22:30:12 -08:00
|
|
|
|
/// assert_eq!(s, "olleh");
|
2014-07-27 12:40:39 +02:00
|
|
|
|
/// ```
|
2015-01-10 11:07:14 +01:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-05 13:48:20 -05:00
|
|
|
|
pub unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8> {
|
2014-04-12 22:44:31 +10:00
|
|
|
|
&mut self.vec
|
|
|
|
|
}
|
2014-04-02 16:54:22 -07:00
|
|
|
|
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Returns the length of this `String`, in bytes.
|
2014-10-30 13:43:24 -07:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-10-30 13:43:24 -07:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2014-10-30 13:43:24 -07:00
|
|
|
|
/// ```
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// let a = String::from("foo");
|
|
|
|
|
///
|
2014-10-30 13:43:24 -07:00
|
|
|
|
/// assert_eq!(a.len(), 3);
|
|
|
|
|
/// ```
|
2014-04-02 16:54:22 -07:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-11-24 11:23:48 +13:00
|
|
|
|
pub fn len(&self) -> usize {
|
|
|
|
|
self.vec.len()
|
|
|
|
|
}
|
2014-04-02 16:54:22 -07:00
|
|
|
|
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Returns `true` if this `String` has a length of zero.
|
|
|
|
|
///
|
|
|
|
|
/// Returns `false` otherwise.
|
2014-10-30 13:43:24 -07:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-10-30 13:43:24 -07:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2014-10-30 13:43:24 -07:00
|
|
|
|
/// ```
|
|
|
|
|
/// let mut v = String::new();
|
|
|
|
|
/// assert!(v.is_empty());
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2014-10-30 13:43:24 -07:00
|
|
|
|
/// v.push('a');
|
|
|
|
|
/// assert!(!v.is_empty());
|
|
|
|
|
/// ```
|
2015-01-10 11:07:14 +01:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-11-24 11:23:48 +13:00
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
|
|
|
self.len() == 0
|
|
|
|
|
}
|
2014-10-30 13:43:24 -07:00
|
|
|
|
|
2017-02-16 22:49:46 -08:00
|
|
|
|
/// Splits the string into two at the given index.
|
2016-11-28 13:54:55 -05:00
|
|
|
|
///
|
2017-02-16 22:49:46 -08:00
|
|
|
|
/// Returns a newly allocated `String`. `self` contains bytes `[0, at)`, and
|
|
|
|
|
/// the returned `String` contains bytes `[at, len)`. `at` must be on the
|
|
|
|
|
/// boundary of a UTF-8 code point.
|
2016-11-28 13:54:55 -05:00
|
|
|
|
///
|
2017-02-16 22:49:46 -08:00
|
|
|
|
/// Note that the capacity of `self` does not change.
|
2016-11-28 13:54:55 -05:00
|
|
|
|
///
|
|
|
|
|
/// # Panics
|
|
|
|
|
///
|
2017-02-16 22:49:46 -08:00
|
|
|
|
/// Panics if `at` is not on a `UTF-8` code point boundary, or if it is beyond the last
|
2016-11-28 13:54:55 -05:00
|
|
|
|
/// code point of the string.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// # fn main() {
|
|
|
|
|
/// let mut hello = String::from("Hello, World!");
|
|
|
|
|
/// let world = hello.split_off(7);
|
|
|
|
|
/// assert_eq!(hello, "Hello, ");
|
|
|
|
|
/// assert_eq!(world, "World!");
|
|
|
|
|
/// # }
|
|
|
|
|
/// ```
|
|
|
|
|
#[inline]
|
2017-01-25 15:37:20 -08:00
|
|
|
|
#[stable(feature = "string_split_off", since = "1.16.0")]
|
2017-02-16 22:49:46 -08:00
|
|
|
|
pub fn split_off(&mut self, at: usize) -> String {
|
|
|
|
|
assert!(self.is_char_boundary(at));
|
|
|
|
|
let other = self.vec.split_off(at);
|
2016-11-28 13:54:55 -05:00
|
|
|
|
unsafe { String::from_utf8_unchecked(other) }
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Truncates this `String`, removing all contents.
|
|
|
|
|
///
|
|
|
|
|
/// While this means the `String` will have a length of zero, it does not
|
|
|
|
|
/// touch its capacity.
|
2014-10-30 13:43:24 -07:00
|
|
|
|
///
|
2014-12-08 23:28:07 -06:00
|
|
|
|
/// # Examples
|
2014-10-30 13:43:24 -07:00
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2014-10-30 13:43:24 -07:00
|
|
|
|
/// ```
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// let mut s = String::from("foo");
|
|
|
|
|
///
|
2014-10-30 13:43:24 -07:00
|
|
|
|
/// s.clear();
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
2014-10-30 13:43:24 -07:00
|
|
|
|
/// assert!(s.is_empty());
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// assert_eq!(0, s.len());
|
|
|
|
|
/// assert_eq!(3, s.capacity());
|
2014-10-30 13:43:24 -07:00
|
|
|
|
/// ```
|
2014-05-11 03:49:09 -07:00
|
|
|
|
#[inline]
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-10-30 13:43:24 -07:00
|
|
|
|
pub fn clear(&mut self) {
|
2014-05-11 03:49:09 -07:00
|
|
|
|
self.vec.clear()
|
|
|
|
|
}
|
2015-05-01 15:34:25 +02:00
|
|
|
|
|
2017-04-08 15:55:53 -05:00
|
|
|
|
/// Creates a draining iterator that removes the specified range in the string
|
2015-12-09 00:04:54 +02:00
|
|
|
|
/// and yields the removed chars.
|
|
|
|
|
///
|
|
|
|
|
/// Note: The element range is removed even if the iterator is not
|
|
|
|
|
/// consumed until the end.
|
2015-05-01 15:34:25 +02:00
|
|
|
|
///
|
|
|
|
|
/// # Panics
|
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Panics if the starting point or end point do not lie on a [`char`]
|
|
|
|
|
/// boundary, or if they're out of bounds.
|
|
|
|
|
///
|
2016-03-07 23:55:52 -08:00
|
|
|
|
/// [`char`]: ../../std/primitive.char.html
|
2015-05-01 15:34:25 +02:00
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
2015-05-01 15:34:25 +02:00
|
|
|
|
/// ```
|
|
|
|
|
/// let mut s = String::from("α is alpha, β is beta");
|
|
|
|
|
/// let beta_offset = s.find('β').unwrap_or(s.len());
|
|
|
|
|
///
|
|
|
|
|
/// // Remove the range up until the β from the string
|
|
|
|
|
/// let t: String = s.drain(..beta_offset).collect();
|
|
|
|
|
/// assert_eq!(t, "α is alpha, ");
|
|
|
|
|
/// assert_eq!(s, "β is beta");
|
|
|
|
|
///
|
|
|
|
|
/// // A full range clears the string
|
|
|
|
|
/// s.drain(..);
|
|
|
|
|
/// assert_eq!(s, "");
|
|
|
|
|
/// ```
|
2015-12-02 17:31:49 -08:00
|
|
|
|
#[stable(feature = "drain", since = "1.6.0")]
|
2015-11-24 11:23:48 +13:00
|
|
|
|
pub fn drain<R>(&mut self, range: R) -> Drain
|
2018-03-19 09:26:29 +01:00
|
|
|
|
where R: RangeBounds<usize>
|
2015-11-24 11:23:48 +13:00
|
|
|
|
{
|
2015-05-01 15:34:25 +02:00
|
|
|
|
// Memory safety
|
|
|
|
|
//
|
|
|
|
|
// The String version of Drain does not have the memory safety issues
|
|
|
|
|
// of the vector version. The data is just plain bytes.
|
|
|
|
|
// Because the range removal happens in Drop, if the Drain iterator is leaked,
|
|
|
|
|
// the removal will not happen.
|
|
|
|
|
let len = self.len();
|
2016-12-23 19:15:56 +00:00
|
|
|
|
let start = match range.start() {
|
|
|
|
|
Included(&n) => n,
|
|
|
|
|
Excluded(&n) => n + 1,
|
|
|
|
|
Unbounded => 0,
|
|
|
|
|
};
|
|
|
|
|
let end = match range.end() {
|
|
|
|
|
Included(&n) => n + 1,
|
|
|
|
|
Excluded(&n) => n,
|
|
|
|
|
Unbounded => len,
|
|
|
|
|
};
|
2015-05-01 15:34:25 +02:00
|
|
|
|
|
|
|
|
|
// Take out two simultaneous borrows. The &mut String won't be accessed
|
|
|
|
|
// until iteration is over, in Drop.
|
|
|
|
|
let self_ptr = self as *mut _;
|
|
|
|
|
// slicing does the appropriate bounds checks
|
|
|
|
|
let chars_iter = self[start..end].chars();
|
|
|
|
|
|
|
|
|
|
Drain {
|
2017-08-06 22:54:09 -07:00
|
|
|
|
start,
|
|
|
|
|
end,
|
2015-05-01 15:34:25 +02:00
|
|
|
|
iter: chars_iter,
|
|
|
|
|
string: self_ptr,
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-07-10 00:04:06 -07:00
|
|
|
|
|
2018-04-01 22:50:22 -06:00
|
|
|
|
/// Removes the specified range in the string,
|
2017-08-22 15:24:25 -05:00
|
|
|
|
/// and replaces it with the given string.
|
|
|
|
|
/// The given string doesn't need to be the same length as the range.
|
2017-04-08 15:55:53 -05:00
|
|
|
|
///
|
|
|
|
|
/// # Panics
|
|
|
|
|
///
|
|
|
|
|
/// Panics if the starting point or end point do not lie on a [`char`]
|
|
|
|
|
/// boundary, or if they're out of bounds.
|
|
|
|
|
///
|
|
|
|
|
/// [`char`]: ../../std/primitive.char.html
|
2017-08-22 15:24:25 -05:00
|
|
|
|
/// [`Vec::splice`]: ../../std/vec/struct.Vec.html#method.splice
|
2017-04-08 15:55:53 -05:00
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let mut s = String::from("α is alpha, β is beta");
|
|
|
|
|
/// let beta_offset = s.find('β').unwrap_or(s.len());
|
|
|
|
|
///
|
|
|
|
|
/// // Replace the range up until the β from the string
|
2018-04-01 22:50:22 -06:00
|
|
|
|
/// s.replace_range(..beta_offset, "Α is capital alpha; ");
|
2017-04-08 15:55:53 -05:00
|
|
|
|
/// assert_eq!(s, "Α is capital alpha; β is beta");
|
|
|
|
|
/// ```
|
2018-04-01 22:50:22 -06:00
|
|
|
|
#[stable(feature = "splice", since = "1.27.0")]
|
|
|
|
|
pub fn replace_range<R>(&mut self, range: R, replace_with: &str)
|
2018-03-19 09:26:29 +01:00
|
|
|
|
where R: RangeBounds<usize>
|
2017-04-08 15:55:53 -05:00
|
|
|
|
{
|
|
|
|
|
// Memory safety
|
|
|
|
|
//
|
2018-04-01 22:50:22 -06:00
|
|
|
|
// Replace_range does not have the memory safety issues of a vector Splice.
|
2017-04-08 15:55:53 -05:00
|
|
|
|
// of the vector version. The data is just plain bytes.
|
2017-08-22 15:24:25 -05:00
|
|
|
|
|
|
|
|
|
match range.start() {
|
|
|
|
|
Included(&n) => assert!(self.is_char_boundary(n)),
|
|
|
|
|
Excluded(&n) => assert!(self.is_char_boundary(n + 1)),
|
|
|
|
|
Unbounded => {},
|
2017-04-08 16:12:58 -05:00
|
|
|
|
};
|
2017-08-22 15:24:25 -05:00
|
|
|
|
match range.end() {
|
|
|
|
|
Included(&n) => assert!(self.is_char_boundary(n + 1)),
|
|
|
|
|
Excluded(&n) => assert!(self.is_char_boundary(n)),
|
|
|
|
|
Unbounded => {},
|
2017-04-08 16:12:58 -05:00
|
|
|
|
};
|
2017-04-08 15:55:53 -05:00
|
|
|
|
|
2017-08-22 15:24:25 -05:00
|
|
|
|
unsafe {
|
|
|
|
|
self.as_mut_vec()
|
|
|
|
|
}.splice(range, replace_with.bytes());
|
2017-04-08 15:55:53 -05:00
|
|
|
|
}
|
|
|
|
|
|
2017-08-18 17:17:46 +02:00
|
|
|
|
/// Converts this `String` into a [`Box`]`<`[`str`]`>`.
|
2015-12-01 16:07:53 -05:00
|
|
|
|
///
|
|
|
|
|
/// This will drop any excess capacity.
|
2015-07-10 00:04:06 -07:00
|
|
|
|
///
|
2017-08-18 17:17:46 +02:00
|
|
|
|
/// [`Box`]: ../../std/boxed/struct.Box.html
|
|
|
|
|
/// [`str`]: ../../std/primitive.str.html
|
|
|
|
|
///
|
2015-12-01 16:07:53 -05:00
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let s = String::from("hello");
|
|
|
|
|
///
|
|
|
|
|
/// let b = s.into_boxed_str();
|
|
|
|
|
/// ```
|
2015-09-10 13:26:44 -07:00
|
|
|
|
#[stable(feature = "box_str", since = "1.4.0")]
|
2018-03-31 23:19:02 +02:00
|
|
|
|
#[inline]
|
2015-08-13 14:02:00 +02:00
|
|
|
|
pub fn into_boxed_str(self) -> Box<str> {
|
2015-07-10 00:04:06 -07:00
|
|
|
|
let slice = self.vec.into_boxed_slice();
|
2017-06-13 15:52:59 -07:00
|
|
|
|
unsafe { from_boxed_utf8_unchecked(slice) }
|
2015-07-10 00:04:06 -07:00
|
|
|
|
}
|
2014-05-11 03:49:09 -07:00
|
|
|
|
}
|
|
|
|
|
|
2014-12-28 10:29:56 -08:00
|
|
|
|
impl FromUtf8Error {
|
2017-03-06 09:03:31 +03:00
|
|
|
|
/// Returns a slice of [`u8`]s bytes that were attempted to convert to a `String`.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// // some invalid bytes, in a vector
|
|
|
|
|
/// let bytes = vec![0, 159];
|
|
|
|
|
///
|
|
|
|
|
/// let value = String::from_utf8(bytes);
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(&[0, 159], value.unwrap_err().as_bytes());
|
|
|
|
|
/// ```
|
2018-03-17 21:41:14 +00:00
|
|
|
|
#[stable(feature = "from_utf8_error_as_bytes", since = "1.26.0")]
|
2017-03-06 09:03:31 +03:00
|
|
|
|
pub fn as_bytes(&self) -> &[u8] {
|
|
|
|
|
&self.bytes[..]
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-30 15:48:28 -05:00
|
|
|
|
/// Returns the bytes that were attempted to convert to a `String`.
|
|
|
|
|
///
|
|
|
|
|
/// This method is carefully constructed to avoid allocation. It will
|
|
|
|
|
/// consume the error, moving out the bytes, so that a copy of the bytes
|
|
|
|
|
/// does not need to be made.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// // some invalid bytes, in a vector
|
|
|
|
|
/// let bytes = vec![0, 159];
|
|
|
|
|
///
|
|
|
|
|
/// let value = String::from_utf8(bytes);
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(vec![0, 159], value.unwrap_err().into_bytes());
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-11-24 11:23:48 +13:00
|
|
|
|
pub fn into_bytes(self) -> Vec<u8> {
|
|
|
|
|
self.bytes
|
|
|
|
|
}
|
2014-12-28 10:29:56 -08:00
|
|
|
|
|
2015-11-30 15:48:28 -05:00
|
|
|
|
/// Fetch a `Utf8Error` to get more details about the conversion failure.
|
|
|
|
|
///
|
|
|
|
|
/// The [`Utf8Error`] type provided by [`std::str`] represents an error that may
|
|
|
|
|
/// occur when converting a slice of [`u8`]s to a [`&str`]. In this sense, it's
|
|
|
|
|
/// an analogue to `FromUtf8Error`. See its documentation for more details
|
|
|
|
|
/// on using it.
|
|
|
|
|
///
|
2016-03-07 23:55:52 -08:00
|
|
|
|
/// [`Utf8Error`]: ../../std/str/struct.Utf8Error.html
|
|
|
|
|
/// [`std::str`]: ../../std/str/index.html
|
|
|
|
|
/// [`u8`]: ../../std/primitive.u8.html
|
|
|
|
|
/// [`&str`]: ../../std/primitive.str.html
|
2015-11-30 15:48:28 -05:00
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// // some invalid bytes, in a vector
|
|
|
|
|
/// let bytes = vec![0, 159];
|
|
|
|
|
///
|
|
|
|
|
/// let error = String::from_utf8(bytes).unwrap_err().utf8_error();
|
|
|
|
|
///
|
|
|
|
|
/// // the first byte is invalid here
|
|
|
|
|
/// assert_eq!(1, error.valid_up_to());
|
|
|
|
|
/// ```
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-11-24 11:23:48 +13:00
|
|
|
|
pub fn utf8_error(&self) -> Utf8Error {
|
|
|
|
|
self.error
|
|
|
|
|
}
|
2014-12-28 10:29:56 -08:00
|
|
|
|
}
|
|
|
|
|
|
2015-01-24 09:15:42 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-01-20 15:45:07 -08:00
|
|
|
|
impl fmt::Display for FromUtf8Error {
|
2014-12-28 10:29:56 -08:00
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2015-01-20 15:45:07 -08:00
|
|
|
|
fmt::Display::fmt(&self.error, f)
|
2014-12-20 00:09:35 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-24 09:15:42 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-01-20 15:45:07 -08:00
|
|
|
|
impl fmt::Display for FromUtf16Error {
|
2014-12-28 10:29:56 -08:00
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2015-01-20 15:45:07 -08:00
|
|
|
|
fmt::Display::fmt("invalid utf-16: lone surrogate found", f)
|
2014-12-20 00:09:35 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-23 08:49:50 -04:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl Clone for String {
|
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
|
String { vec: self.vec.clone() }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn clone_from(&mut self, source: &Self) {
|
|
|
|
|
self.vec.clone_from(&source.vec);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-05-22 16:57:53 -07:00
|
|
|
|
impl FromIterator<char> for String {
|
2016-03-28 13:55:47 -04:00
|
|
|
|
fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> String {
|
2014-05-22 16:57:53 -07:00
|
|
|
|
let mut buf = String::new();
|
2016-03-28 13:55:47 -04:00
|
|
|
|
buf.extend(iter);
|
2014-04-02 16:54:22 -07:00
|
|
|
|
buf
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-22 00:06:40 -08:00
|
|
|
|
#[stable(feature = "string_from_iter_by_ref", since = "1.17.0")]
|
|
|
|
|
impl<'a> FromIterator<&'a char> for String {
|
|
|
|
|
fn from_iter<I: IntoIterator<Item = &'a char>>(iter: I) -> String {
|
|
|
|
|
let mut buf = String::new();
|
|
|
|
|
buf.extend(iter);
|
|
|
|
|
buf
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-07 21:32:00 +01:00
|
|
|
|
impl<'a> FromIterator<&'a str> for String {
|
2016-03-28 13:55:47 -04:00
|
|
|
|
fn from_iter<I: IntoIterator<Item = &'a str>>(iter: I) -> String {
|
2014-12-07 21:32:00 +01:00
|
|
|
|
let mut buf = String::new();
|
2016-03-28 13:55:47 -04:00
|
|
|
|
buf.extend(iter);
|
2015-08-27 08:47:08 -07:00
|
|
|
|
buf
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "extend_string", since = "1.4.0")]
|
|
|
|
|
impl FromIterator<String> for String {
|
2016-03-28 13:55:47 -04:00
|
|
|
|
fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> String {
|
2015-08-27 08:47:08 -07:00
|
|
|
|
let mut buf = String::new();
|
2016-03-28 13:55:47 -04:00
|
|
|
|
buf.extend(iter);
|
2014-12-07 21:32:00 +01:00
|
|
|
|
buf
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-21 13:25:48 -04:00
|
|
|
|
#[stable(feature = "herd_cows", since = "1.19.0")]
|
|
|
|
|
impl<'a> FromIterator<Cow<'a, str>> for String {
|
|
|
|
|
fn from_iter<I: IntoIterator<Item = Cow<'a, str>>>(iter: I) -> String {
|
|
|
|
|
let mut buf = String::new();
|
|
|
|
|
buf.extend(iter);
|
|
|
|
|
buf
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-30 15:24:39 -07:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-08 01:39:39 +01:00
|
|
|
|
impl Extend<char> for String {
|
2016-03-28 13:55:47 -04:00
|
|
|
|
fn extend<I: IntoIterator<Item = char>>(&mut self, iter: I) {
|
|
|
|
|
let iterator = iter.into_iter();
|
2014-12-07 21:31:24 +01:00
|
|
|
|
let (lower_bound, _) = iterator.size_hint();
|
|
|
|
|
self.reserve(lower_bound);
|
2014-04-02 16:54:22 -07:00
|
|
|
|
for ch in iterator {
|
2014-09-22 08:28:35 -07:00
|
|
|
|
self.push(ch)
|
2014-04-02 16:54:22 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-03 12:38:42 +02:00
|
|
|
|
#[stable(feature = "extend_ref", since = "1.2.0")]
|
|
|
|
|
impl<'a> Extend<&'a char> for String {
|
2016-03-28 13:55:47 -04:00
|
|
|
|
fn extend<I: IntoIterator<Item = &'a char>>(&mut self, iter: I) {
|
|
|
|
|
self.extend(iter.into_iter().cloned());
|
2015-06-03 12:38:42 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-30 15:24:39 -07:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-07 21:32:00 +01:00
|
|
|
|
impl<'a> Extend<&'a str> for String {
|
2016-03-28 13:55:47 -04:00
|
|
|
|
fn extend<I: IntoIterator<Item = &'a str>>(&mut self, iter: I) {
|
|
|
|
|
for s in iter {
|
2014-12-07 21:32:00 +01:00
|
|
|
|
self.push_str(s)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-27 08:47:08 -07:00
|
|
|
|
#[stable(feature = "extend_string", since = "1.4.0")]
|
|
|
|
|
impl Extend<String> for String {
|
2016-03-28 13:55:47 -04:00
|
|
|
|
fn extend<I: IntoIterator<Item = String>>(&mut self, iter: I) {
|
|
|
|
|
for s in iter {
|
2015-08-27 08:47:08 -07:00
|
|
|
|
self.push_str(&s)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-21 13:25:48 -04:00
|
|
|
|
#[stable(feature = "herd_cows", since = "1.19.0")]
|
|
|
|
|
impl<'a> Extend<Cow<'a, str>> for String {
|
|
|
|
|
fn extend<I: IntoIterator<Item = Cow<'a, str>>>(&mut self, iter: I) {
|
|
|
|
|
for s in iter {
|
|
|
|
|
self.push_str(&s)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-21 06:02:56 -04:00
|
|
|
|
/// A convenience impl that delegates to the impl for `&str`
|
2015-11-16 19:54:28 +03:00
|
|
|
|
#[unstable(feature = "pattern",
|
|
|
|
|
reason = "API not fully fleshed out and ready to be stabilized",
|
|
|
|
|
issue = "27721")]
|
2015-03-21 06:02:56 -04:00
|
|
|
|
impl<'a, 'b> Pattern<'a> for &'b String {
|
|
|
|
|
type Searcher = <&'b str as Pattern<'a>>::Searcher;
|
|
|
|
|
|
|
|
|
|
fn into_searcher(self, haystack: &'a str) -> <&'b str as Pattern<'a>>::Searcher {
|
|
|
|
|
self[..].into_searcher(haystack)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn is_contained_in(self, haystack: &'a str) -> bool {
|
|
|
|
|
self[..].is_contained_in(haystack)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn is_prefix_of(self, haystack: &'a str) -> bool {
|
|
|
|
|
self[..].is_prefix_of(haystack)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-21 00:14:05 -05:00
|
|
|
|
impl PartialEq for String {
|
|
|
|
|
#[inline]
|
2015-11-24 11:23:48 +13:00
|
|
|
|
fn eq(&self, other: &String) -> bool {
|
|
|
|
|
PartialEq::eq(&self[..], &other[..])
|
|
|
|
|
}
|
2014-11-21 00:14:05 -05:00
|
|
|
|
#[inline]
|
2015-11-24 11:23:48 +13:00
|
|
|
|
fn ne(&self, other: &String) -> bool {
|
|
|
|
|
PartialEq::ne(&self[..], &other[..])
|
|
|
|
|
}
|
2014-11-21 00:14:05 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
macro_rules! impl_eq {
|
|
|
|
|
($lhs:ty, $rhs: ty) => {
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-11-03 04:54:32 +00:00
|
|
|
|
impl<'a, 'b> PartialEq<$rhs> for $lhs {
|
2014-11-21 00:14:05 -05:00
|
|
|
|
#[inline]
|
2015-04-02 18:50:09 +03:00
|
|
|
|
fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&self[..], &other[..]) }
|
2014-11-21 00:14:05 -05:00
|
|
|
|
#[inline]
|
2015-04-02 18:50:09 +03:00
|
|
|
|
fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&self[..], &other[..]) }
|
2014-11-21 00:14:05 -05:00
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-11-03 04:54:32 +00:00
|
|
|
|
impl<'a, 'b> PartialEq<$lhs> for $rhs {
|
2014-11-21 00:14:05 -05:00
|
|
|
|
#[inline]
|
2015-04-02 18:50:09 +03:00
|
|
|
|
fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&self[..], &other[..]) }
|
2014-11-21 00:14:05 -05:00
|
|
|
|
#[inline]
|
2015-04-02 18:50:09 +03:00
|
|
|
|
fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&self[..], &other[..]) }
|
2014-11-21 00:14:05 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-02 18:51:14 +03:00
|
|
|
|
impl_eq! { String, str }
|
2014-11-14 09:18:10 -08:00
|
|
|
|
impl_eq! { String, &'a str }
|
2015-04-02 18:51:14 +03:00
|
|
|
|
impl_eq! { Cow<'a, str>, str }
|
2015-11-03 04:54:32 +00:00
|
|
|
|
impl_eq! { Cow<'a, str>, &'b str }
|
2015-02-11 23:16:32 -08:00
|
|
|
|
impl_eq! { Cow<'a, str>, String }
|
2014-11-21 00:14:05 -05:00
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-05-22 16:57:53 -07:00
|
|
|
|
impl Default for String {
|
2016-09-11 17:00:09 +05:30
|
|
|
|
/// Creates an empty `String`.
|
2015-01-10 11:07:14 +01:00
|
|
|
|
#[inline]
|
2014-05-22 16:57:53 -07:00
|
|
|
|
fn default() -> String {
|
|
|
|
|
String::new()
|
2014-05-19 23:19:56 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-01-20 15:45:07 -08:00
|
|
|
|
impl fmt::Display for String {
|
2015-01-10 11:07:14 +01:00
|
|
|
|
#[inline]
|
2014-12-20 00:09:35 -08:00
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2015-01-20 15:45:07 -08:00
|
|
|
|
fmt::Display::fmt(&**self, f)
|
2014-12-20 00:09:35 -08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-24 09:15:42 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-01-20 15:45:07 -08:00
|
|
|
|
impl fmt::Debug for String {
|
2015-01-10 11:07:14 +01:00
|
|
|
|
#[inline]
|
2014-04-02 16:54:22 -07:00
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2015-01-20 15:45:07 -08:00
|
|
|
|
fmt::Debug::fmt(&**self, f)
|
2014-04-02 16:54:22 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-17 20:48:07 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl hash::Hash for String {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn hash<H: hash::Hasher>(&self, hasher: &mut H) {
|
|
|
|
|
(**self).hash(hasher)
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-04-02 16:54:22 -07:00
|
|
|
|
|
2017-02-16 09:18:18 -08:00
|
|
|
|
/// Implements the `+` operator for concatenating two strings.
|
|
|
|
|
///
|
|
|
|
|
/// This consumes the `String` on the left-hand side and re-uses its buffer (growing it if
|
|
|
|
|
/// necessary). This is done to avoid allocating a new `String` and copying the entire contents on
|
|
|
|
|
/// every operation, which would lead to `O(n^2)` running time when building an `n`-byte string by
|
|
|
|
|
/// repeated concatenation.
|
|
|
|
|
///
|
|
|
|
|
/// The string on the right-hand side is only borrowed; its contents are copied into the returned
|
|
|
|
|
/// `String`.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// Concatenating two `String`s takes the first by value and borrows the second:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let a = String::from("hello");
|
|
|
|
|
/// let b = String::from(" world");
|
|
|
|
|
/// let c = a + &b;
|
|
|
|
|
/// // `a` is moved and can no longer be used here.
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
|
|
|
|
/// If you want to keep using the first `String`, you can clone it and append to the clone instead:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let a = String::from("hello");
|
|
|
|
|
/// let b = String::from(" world");
|
|
|
|
|
/// let c = a.clone() + &b;
|
|
|
|
|
/// // `a` is still valid here.
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
|
|
|
|
/// Concatenating `&str` slices can be done by converting the first to a `String`:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let a = "hello";
|
|
|
|
|
/// let b = " world";
|
|
|
|
|
/// let c = a.to_string() + b;
|
|
|
|
|
/// ```
|
2015-04-30 15:24:39 -07:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-12-31 15:45:13 -05:00
|
|
|
|
impl<'a> Add<&'a str> for String {
|
|
|
|
|
type Output = String;
|
|
|
|
|
|
2015-01-10 11:07:14 +01:00
|
|
|
|
#[inline]
|
2014-12-01 14:08:56 -05:00
|
|
|
|
fn add(mut self, other: &str) -> String {
|
|
|
|
|
self.push_str(other);
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-16 09:18:18 -08:00
|
|
|
|
/// Implements the `+=` operator for appending to a `String`.
|
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// This has the same behavior as the [`push_str`] method.
|
2017-02-16 09:18:18 -08:00
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`push_str`]: struct.String.html#method.push_str
|
2016-07-18 14:27:17 -04:00
|
|
|
|
#[stable(feature = "stringaddassign", since = "1.12.0")]
|
2016-07-17 11:31:44 -04:00
|
|
|
|
impl<'a> AddAssign<&'a str> for String {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn add_assign(&mut self, other: &str) {
|
|
|
|
|
self.push_str(other);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-24 09:15:42 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-04 21:17:19 -05:00
|
|
|
|
impl ops::Index<ops::Range<usize>> for String {
|
2015-01-04 17:43:24 +13:00
|
|
|
|
type Output = str;
|
2015-03-21 19:33:27 -04:00
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn index(&self, index: ops::Range<usize>) -> &str {
|
|
|
|
|
&self[..][index]
|
|
|
|
|
}
|
2014-12-31 20:20:40 +13:00
|
|
|
|
}
|
2015-01-24 09:15:42 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-04 21:17:19 -05:00
|
|
|
|
impl ops::Index<ops::RangeTo<usize>> for String {
|
2015-01-04 17:43:24 +13:00
|
|
|
|
type Output = str;
|
2015-03-21 19:33:27 -04:00
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn index(&self, index: ops::RangeTo<usize>) -> &str {
|
|
|
|
|
&self[..][index]
|
|
|
|
|
}
|
2014-12-31 20:20:40 +13:00
|
|
|
|
}
|
2015-01-24 09:15:42 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-04 21:17:19 -05:00
|
|
|
|
impl ops::Index<ops::RangeFrom<usize>> for String {
|
2015-01-04 17:43:24 +13:00
|
|
|
|
type Output = str;
|
2015-03-21 19:33:27 -04:00
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn index(&self, index: ops::RangeFrom<usize>) -> &str {
|
|
|
|
|
&self[..][index]
|
|
|
|
|
}
|
2014-12-31 20:20:40 +13:00
|
|
|
|
}
|
2015-01-28 17:06:46 +13:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl ops::Index<ops::RangeFull> for String {
|
|
|
|
|
type Output = str;
|
2015-03-21 19:33:27 -04:00
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn index(&self, _index: ops::RangeFull) -> &str {
|
2015-07-24 03:04:55 +02:00
|
|
|
|
unsafe { str::from_utf8_unchecked(&self.vec) }
|
2015-03-21 19:33:27 -04:00
|
|
|
|
}
|
2015-01-28 17:06:46 +13:00
|
|
|
|
}
|
2018-01-28 03:09:36 +08:00
|
|
|
|
#[stable(feature = "inclusive_range", since = "1.26.0")]
|
2016-01-28 11:20:48 -05:00
|
|
|
|
impl ops::Index<ops::RangeInclusive<usize>> for String {
|
|
|
|
|
type Output = str;
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn index(&self, index: ops::RangeInclusive<usize>) -> &str {
|
|
|
|
|
Index::index(&**self, index)
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-01-28 03:09:36 +08:00
|
|
|
|
#[stable(feature = "inclusive_range", since = "1.26.0")]
|
2016-01-28 11:20:48 -05:00
|
|
|
|
impl ops::Index<ops::RangeToInclusive<usize>> for String {
|
|
|
|
|
type Output = str;
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn index(&self, index: ops::RangeToInclusive<usize>) -> &str {
|
|
|
|
|
Index::index(&**self, index)
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-09-26 21:46:22 -07:00
|
|
|
|
|
2017-05-20 08:38:39 +01:00
|
|
|
|
#[stable(feature = "derefmut_for_string", since = "1.3.0")]
|
2015-06-15 18:33:21 +02:00
|
|
|
|
impl ops::IndexMut<ops::Range<usize>> for String {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn index_mut(&mut self, index: ops::Range<usize>) -> &mut str {
|
|
|
|
|
&mut self[..][index]
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-05-20 08:38:39 +01:00
|
|
|
|
#[stable(feature = "derefmut_for_string", since = "1.3.0")]
|
2015-06-15 18:33:21 +02:00
|
|
|
|
impl ops::IndexMut<ops::RangeTo<usize>> for String {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut str {
|
|
|
|
|
&mut self[..][index]
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-05-20 08:38:39 +01:00
|
|
|
|
#[stable(feature = "derefmut_for_string", since = "1.3.0")]
|
2015-06-15 18:33:21 +02:00
|
|
|
|
impl ops::IndexMut<ops::RangeFrom<usize>> for String {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut str {
|
|
|
|
|
&mut self[..][index]
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-05-20 08:38:39 +01:00
|
|
|
|
#[stable(feature = "derefmut_for_string", since = "1.3.0")]
|
2015-06-15 18:33:21 +02:00
|
|
|
|
impl ops::IndexMut<ops::RangeFull> for String {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn index_mut(&mut self, _index: ops::RangeFull) -> &mut str {
|
2017-03-10 12:10:26 -05:00
|
|
|
|
unsafe { str::from_utf8_unchecked_mut(&mut *self.vec) }
|
2015-06-15 18:33:21 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2018-01-28 03:09:36 +08:00
|
|
|
|
#[stable(feature = "inclusive_range", since = "1.26.0")]
|
2016-01-28 11:20:48 -05:00
|
|
|
|
impl ops::IndexMut<ops::RangeInclusive<usize>> for String {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn index_mut(&mut self, index: ops::RangeInclusive<usize>) -> &mut str {
|
|
|
|
|
IndexMut::index_mut(&mut **self, index)
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-01-28 03:09:36 +08:00
|
|
|
|
#[stable(feature = "inclusive_range", since = "1.26.0")]
|
2016-01-28 11:20:48 -05:00
|
|
|
|
impl ops::IndexMut<ops::RangeToInclusive<usize>> for String {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn index_mut(&mut self, index: ops::RangeToInclusive<usize>) -> &mut str {
|
|
|
|
|
IndexMut::index_mut(&mut **self, index)
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-06-15 18:33:21 +02:00
|
|
|
|
|
2015-01-23 21:48:20 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-01-01 14:53:20 -05:00
|
|
|
|
impl ops::Deref for String {
|
|
|
|
|
type Target = str;
|
|
|
|
|
|
2015-01-10 11:07:14 +01:00
|
|
|
|
#[inline]
|
2015-02-05 13:48:20 -05:00
|
|
|
|
fn deref(&self) -> &str {
|
2015-07-24 03:04:55 +02:00
|
|
|
|
unsafe { str::from_utf8_unchecked(&self.vec) }
|
std: Stabilize the std::str module
This commit starts out by consolidating all `str` extension traits into one
`StrExt` trait to be included in the prelude. This means that
`UnicodeStrPrelude`, `StrPrelude`, and `StrAllocating` have all been merged into
one `StrExt` exported by the standard library. Some functionality is currently
duplicated with the `StrExt` present in libcore.
This commit also currently avoids any methods which require any form of pattern
to operate. These functions will be stabilized via a separate RFC.
Next, stability of methods and structures are as follows:
Stable
* from_utf8_unchecked
* CowString - after moving to std::string
* StrExt::as_bytes
* StrExt::as_ptr
* StrExt::bytes/Bytes - also made a struct instead of a typedef
* StrExt::char_indices/CharIndices - CharOffsets was renamed
* StrExt::chars/Chars
* StrExt::is_empty
* StrExt::len
* StrExt::lines/Lines
* StrExt::lines_any/LinesAny
* StrExt::slice_unchecked
* StrExt::trim
* StrExt::trim_left
* StrExt::trim_right
* StrExt::words/Words - also made a struct instead of a typedef
Unstable
* from_utf8 - the error type was changed to a `Result`, but the error type has
yet to prove itself
* from_c_str - this function will be handled by the c_str RFC
* FromStr - this trait will have an associated error type eventually
* StrExt::escape_default - needs iterators at least, unsure if it should make
the cut
* StrExt::escape_unicode - needs iterators at least, unsure if it should make
the cut
* StrExt::slice_chars - this function has yet to prove itself
* StrExt::slice_shift_char - awaiting conventions about slicing and shifting
* StrExt::graphemes/Graphemes - this functionality may only be in libunicode
* StrExt::grapheme_indices/GraphemeIndices - this functionality may only be in
libunicode
* StrExt::width - this functionality may only be in libunicode
* StrExt::utf16_units - this functionality may only be in libunicode
* StrExt::nfd_chars - this functionality may only be in libunicode
* StrExt::nfkd_chars - this functionality may only be in libunicode
* StrExt::nfc_chars - this functionality may only be in libunicode
* StrExt::nfkc_chars - this functionality may only be in libunicode
* StrExt::is_char_boundary - naming is uncertain with container conventions
* StrExt::char_range_at - naming is uncertain with container conventions
* StrExt::char_range_at_reverse - naming is uncertain with container conventions
* StrExt::char_at - naming is uncertain with container conventions
* StrExt::char_at_reverse - naming is uncertain with container conventions
* StrVector::concat - this functionality may be replaced with iterators, but
it's not certain at this time
* StrVector::connect - as with concat, may be deprecated in favor of iterators
Deprecated
* StrAllocating and UnicodeStrPrelude have been merged into StrExit
* eq_slice - compiler implementation detail
* from_str - use the inherent parse() method
* is_utf8 - call from_utf8 instead
* replace - call the method instead
* truncate_utf16_at_nul - this is an implementation detail of windows and does
not need to be exposed.
* utf8_char_width - moved to libunicode
* utf16_items - moved to libunicode
* is_utf16 - moved to libunicode
* Utf16Items - moved to libunicode
* Utf16Item - moved to libunicode
* Utf16Encoder - moved to libunicode
* AnyLines - renamed to LinesAny and made a struct
* SendStr - use CowString<'static> instead
* str::raw - all functionality is deprecated
* StrExt::into_string - call to_string() instead
* StrExt::repeat - use iterators instead
* StrExt::char_len - use .chars().count() instead
* StrExt::is_alphanumeric - use .chars().all(..)
* StrExt::is_whitespace - use .chars().all(..)
Pending deprecation -- while slicing syntax is being worked out, these methods
are all #[unstable]
* Str - while currently used for generic programming, this trait will be
replaced with one of [], deref coercions, or a generic conversion trait.
* StrExt::slice - use slicing syntax instead
* StrExt::slice_to - use slicing syntax instead
* StrExt::slice_from - use slicing syntax instead
* StrExt::lev_distance - deprecated with no replacement
Awaiting stabilization due to patterns and/or matching
* StrExt::contains
* StrExt::contains_char
* StrExt::split
* StrExt::splitn
* StrExt::split_terminator
* StrExt::rsplitn
* StrExt::match_indices
* StrExt::split_str
* StrExt::starts_with
* StrExt::ends_with
* StrExt::trim_chars
* StrExt::trim_left_chars
* StrExt::trim_right_chars
* StrExt::find
* StrExt::rfind
* StrExt::find_str
* StrExt::subslice_offset
2014-12-10 09:02:31 -08:00
|
|
|
|
}
|
2014-10-29 15:26:29 -07:00
|
|
|
|
}
|
|
|
|
|
|
2017-05-20 08:38:39 +01:00
|
|
|
|
#[stable(feature = "derefmut_for_string", since = "1.3.0")]
|
2015-06-12 10:29:23 +02:00
|
|
|
|
impl ops::DerefMut for String {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn deref_mut(&mut self) -> &mut str {
|
2017-03-10 12:10:26 -05:00
|
|
|
|
unsafe { str::from_utf8_unchecked_mut(&mut *self.vec) }
|
2015-06-12 10:29:23 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-30 14:47:14 -05:00
|
|
|
|
/// An error when parsing a `String`.
|
|
|
|
|
///
|
|
|
|
|
/// This `enum` is slightly awkward: it will never actually exist. This error is
|
|
|
|
|
/// part of the type signature of the implementation of [`FromStr`] on
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`String`]. The return type of [`from_str`], requires that an error be
|
2015-11-30 14:47:14 -05:00
|
|
|
|
/// defined, but, given that a [`String`] can always be made into a new
|
|
|
|
|
/// [`String`] without error, this type will never actually be returned. As
|
|
|
|
|
/// such, it is only here to satisfy said signature, and is useless otherwise.
|
|
|
|
|
///
|
2016-03-07 23:55:52 -08:00
|
|
|
|
/// [`FromStr`]: ../../std/str/trait.FromStr.html
|
2015-11-30 14:47:14 -05:00
|
|
|
|
/// [`String`]: struct.String.html
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`from_str`]: ../../std/str/trait.FromStr.html#tymethod.from_str
|
std: Stabilize library APIs for 1.5
This commit stabilizes and deprecates library APIs whose FCP has closed in the
last cycle, specifically:
Stabilized APIs:
* `fs::canonicalize`
* `Path::{metadata, symlink_metadata, canonicalize, read_link, read_dir, exists,
is_file, is_dir}` - all moved to inherent methods from the `PathExt` trait.
* `Formatter::fill`
* `Formatter::width`
* `Formatter::precision`
* `Formatter::sign_plus`
* `Formatter::sign_minus`
* `Formatter::alternate`
* `Formatter::sign_aware_zero_pad`
* `string::ParseError`
* `Utf8Error::valid_up_to`
* `Iterator::{cmp, partial_cmp, eq, ne, lt, le, gt, ge}`
* `<[T]>::split_{first,last}{,_mut}`
* `Condvar::wait_timeout` - note that `wait_timeout_ms` is not yet deprecated
but will be once 1.5 is released.
* `str::{R,}MatchIndices`
* `str::{r,}match_indices`
* `char::from_u32_unchecked`
* `VecDeque::insert`
* `VecDeque::shrink_to_fit`
* `VecDeque::as_slices`
* `VecDeque::as_mut_slices`
* `VecDeque::swap_remove_front` - (renamed from `swap_front_remove`)
* `VecDeque::swap_remove_back` - (renamed from `swap_back_remove`)
* `Vec::resize`
* `str::slice_mut_unchecked`
* `FileTypeExt`
* `FileTypeExt::{is_block_device, is_char_device, is_fifo, is_socket}`
* `BinaryHeap::from` - `from_vec` deprecated in favor of this
* `BinaryHeap::into_vec` - plus a `Into` impl
* `BinaryHeap::into_sorted_vec`
Deprecated APIs
* `slice::ref_slice`
* `slice::mut_ref_slice`
* `iter::{range_inclusive, RangeInclusive}`
* `std::dynamic_lib`
Closes #27706
Closes #27725
cc #27726 (align not stabilized yet)
Closes #27734
Closes #27737
Closes #27742
Closes #27743
Closes #27772
Closes #27774
Closes #27777
Closes #27781
cc #27788 (a few remaining methods though)
Closes #27790
Closes #27793
Closes #27796
Closes #27810
cc #28147 (not all parts stabilized)
2015-10-22 16:28:45 -07:00
|
|
|
|
#[stable(feature = "str_parse_error", since = "1.5.0")]
|
2015-09-24 09:40:50 -07:00
|
|
|
|
#[derive(Copy)]
|
|
|
|
|
pub enum ParseError {}
|
2015-04-30 15:24:39 -07:00
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-15 15:52:00 +11:00
|
|
|
|
impl FromStr for String {
|
2015-04-30 15:24:39 -07:00
|
|
|
|
type Err = ParseError;
|
2014-11-15 15:52:00 +11:00
|
|
|
|
#[inline]
|
2015-04-30 15:24:39 -07:00
|
|
|
|
fn from_str(s: &str) -> Result<String, ParseError> {
|
2015-06-08 16:55:35 +02:00
|
|
|
|
Ok(String::from(s))
|
2014-11-15 15:52:00 +11:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-16 19:54:28 +03:00
|
|
|
|
#[stable(feature = "str_parse_error", since = "1.5.0")]
|
2015-09-24 09:40:50 -07:00
|
|
|
|
impl Clone for ParseError {
|
|
|
|
|
fn clone(&self) -> ParseError {
|
|
|
|
|
match *self {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-16 19:54:28 +03:00
|
|
|
|
#[stable(feature = "str_parse_error", since = "1.5.0")]
|
2015-09-24 09:40:50 -07:00
|
|
|
|
impl fmt::Debug for ParseError {
|
|
|
|
|
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
|
match *self {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-22 13:38:28 -05:00
|
|
|
|
#[stable(feature = "str_parse_error2", since = "1.8.0")]
|
|
|
|
|
impl fmt::Display for ParseError {
|
|
|
|
|
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
|
match *self {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-16 19:54:28 +03:00
|
|
|
|
#[stable(feature = "str_parse_error", since = "1.5.0")]
|
2015-09-24 09:40:50 -07:00
|
|
|
|
impl PartialEq for ParseError {
|
|
|
|
|
fn eq(&self, _: &ParseError) -> bool {
|
|
|
|
|
match *self {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-16 19:54:28 +03:00
|
|
|
|
#[stable(feature = "str_parse_error", since = "1.5.0")]
|
2015-09-24 09:40:50 -07:00
|
|
|
|
impl Eq for ParseError {}
|
|
|
|
|
|
2015-11-30 14:36:03 -05:00
|
|
|
|
/// A trait for converting a value to a `String`.
|
|
|
|
|
///
|
|
|
|
|
/// This trait is automatically implemented for any type which implements the
|
|
|
|
|
/// [`Display`] trait. As such, `ToString` shouldn't be implemented directly:
|
|
|
|
|
/// [`Display`] should be implemented instead, and you get the `ToString`
|
|
|
|
|
/// implementation for free.
|
|
|
|
|
///
|
2016-03-07 23:55:52 -08:00
|
|
|
|
/// [`Display`]: ../../std/fmt/trait.Display.html
|
std: Stabilize the std::fmt module
This commit performs a final stabilization pass over the std::fmt module,
marking all necessary APIs as stable. One of the more interesting aspects of
this module is that it exposes a good deal of its runtime representation to the
outside world in order for `format_args!` to be able to construct the format
strings. Instead of hacking the compiler to assume that these items are stable,
this commit instead lays out a story for the stabilization and evolution of
these APIs.
There are three primary details used by the `format_args!` macro:
1. `Arguments` - an opaque package of a "compiled format string". This structure
is passed around and the `write` function is the source of truth for
transforming a compiled format string into a string at runtime. This must be
able to be constructed in stable code.
2. `Argument` - an opaque structure representing an argument to a format string.
This is *almost* a trait object as it's just a pointer/function pair, but due
to the function originating from one of many traits, it's not actually a
trait object. Like `Arguments`, this must be constructed from stable code.
3. `fmt::rt` - this module contains the runtime type definitions primarily for
the `rt::Argument` structure. Whenever an argument is formatted with
nonstandard flags, a corresponding `rt::Argument` is generated describing how
the argument is being formatted. This can be used to construct an
`Arguments`.
The primary interface to `std::fmt` is the `Arguments` structure, and as such
this type name is stabilize as-is today. It is expected for libraries to pass
around an `Arguments` structure to represent a pending formatted computation.
The remaining portions are largely "cruft" which would rather not be stabilized,
but due to the stability checks they must be. As a result, almost all pieces
have been renamed to represent that they are "version 1" of the formatting
representation. The theory is that at a later date if we change the
representation of these types we can add new definitions called "version 2" and
corresponding constructors for `Arguments`.
One of the other remaining large questions about the fmt module were how the
pending I/O reform would affect the signatures of methods in the module. Due to
[RFC 526][rfc], however, the writers of fmt are now incompatible with the
writers of io, so this question has largely been solved. As a result the
interfaces are largely stabilized as-is today.
[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0526-fmt-text-writer.md
Specifically, the following changes were made:
* The contents of `fmt::rt` were all moved under `fmt::rt::v1`
* `fmt::rt` is stable
* `fmt::rt::v1` is stable
* `Error` is stable
* `Writer` is stable
* `Writer::write_str` is stable
* `Writer::write_fmt` is stable
* `Formatter` is stable
* `Argument` has been renamed to `ArgumentV1` and is stable
* `ArgumentV1::new` is stable
* `ArgumentV1::from_uint` is stable
* `Arguments::new_v1` is stable (renamed from `new`)
* `Arguments::new_v1_formatted` is stable (renamed from `with_placeholders`)
* All formatting traits are now stable, as well as the `fmt` method.
* `fmt::write` is stable
* `fmt::format` is stable
* `Formatter::pad_integral` is stable
* `Formatter::pad` is stable
* `Formatter::write_str` is stable
* `Formatter::write_fmt` is stable
* Some assorted top level items which were only used by `format_args!` were
removed in favor of static functions on `ArgumentV1` as well.
* The formatting-flag-accessing methods remain unstable
Within the contents of the `fmt::rt::v1` module, the following actions were
taken:
* Reexports of all enum variants were removed
* All prefixes on enum variants were removed
* A few miscellaneous enum variants were renamed
* Otherwise all structs, fields, and variants were marked stable.
In addition to these actions in the `std::fmt` module, many implementations of
`Show` and `String` were stabilized as well.
In some other modules:
* `ToString` is now stable
* `ToString::to_string` is now stable
* `Vec` no longer implements `fmt::Writer` (this has moved to `String`)
This is a breaking change due to all of the changes to the `fmt::rt` module, but
this likely will not have much impact on existing programs.
Closes #20661
[breaking-change]
2015-01-13 15:42:53 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-16 12:38:03 +11:00
|
|
|
|
pub trait ToString {
|
2015-11-30 14:36:03 -05:00
|
|
|
|
/// Converts the given value to a `String`.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// Basic usage:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// let i = 5;
|
|
|
|
|
/// let five = String::from("5");
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(five, i.to_string());
|
|
|
|
|
/// ```
|
type error method suggestions use whitelisted identity-like conversions
Previously, on a type mismatch (and if this wasn't preëmpted by a
higher-priority suggestion), we would look for argumentless methods
returning the expected type, and list them in a `help` note.
This had two major shortcomings. Firstly, a lot of the suggestions didn't
really make sense (if you used a &str where a String was expected,
`.to_ascii_uppercase()` is probably not the solution you were hoping
for). Secondly, we weren't generating suggestions from the most useful
traits!
We address the first problem with an internal
`#[rustc_conversion_suggestion]` attribute meant to mark methods that keep
the "same value" in the relevant sense, just converting the type. We
address the second problem by making `FnCtxt.probe_for_return_type` pass
the `ProbeScope::AllTraits` to `probe_op`: this would seem to be safe
because grep reveals no other callers of `probe_for_return_type`.
Also, structured suggestions are preferred (because they're pretty, but
also for RLS and friends).
Also also, we make the E0055 autoderef recursion limit error use the
one-time-diagnostics set, because we can potentially hit the limit a lot
during probing. (Without this,
test/ui/did_you_mean/recursion_limit_deref.rs would report "aborting due to
51 errors").
Unfortunately, the trait probing is still not all one would hope for: at a
minimum, we don't know how to rule out `into()` in cases where it wouldn't
actually work, and we don't know how to rule in `.to_owned()` where it
would. Issues #46459 and #46460 have been filed and are ref'd in a FIXME.
This is hoped to resolve #42929, #44672, and #45777.
2017-11-19 11:25:35 -08:00
|
|
|
|
#[rustc_conversion_suggestion]
|
std: Stabilize the std::fmt module
This commit performs a final stabilization pass over the std::fmt module,
marking all necessary APIs as stable. One of the more interesting aspects of
this module is that it exposes a good deal of its runtime representation to the
outside world in order for `format_args!` to be able to construct the format
strings. Instead of hacking the compiler to assume that these items are stable,
this commit instead lays out a story for the stabilization and evolution of
these APIs.
There are three primary details used by the `format_args!` macro:
1. `Arguments` - an opaque package of a "compiled format string". This structure
is passed around and the `write` function is the source of truth for
transforming a compiled format string into a string at runtime. This must be
able to be constructed in stable code.
2. `Argument` - an opaque structure representing an argument to a format string.
This is *almost* a trait object as it's just a pointer/function pair, but due
to the function originating from one of many traits, it's not actually a
trait object. Like `Arguments`, this must be constructed from stable code.
3. `fmt::rt` - this module contains the runtime type definitions primarily for
the `rt::Argument` structure. Whenever an argument is formatted with
nonstandard flags, a corresponding `rt::Argument` is generated describing how
the argument is being formatted. This can be used to construct an
`Arguments`.
The primary interface to `std::fmt` is the `Arguments` structure, and as such
this type name is stabilize as-is today. It is expected for libraries to pass
around an `Arguments` structure to represent a pending formatted computation.
The remaining portions are largely "cruft" which would rather not be stabilized,
but due to the stability checks they must be. As a result, almost all pieces
have been renamed to represent that they are "version 1" of the formatting
representation. The theory is that at a later date if we change the
representation of these types we can add new definitions called "version 2" and
corresponding constructors for `Arguments`.
One of the other remaining large questions about the fmt module were how the
pending I/O reform would affect the signatures of methods in the module. Due to
[RFC 526][rfc], however, the writers of fmt are now incompatible with the
writers of io, so this question has largely been solved. As a result the
interfaces are largely stabilized as-is today.
[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0526-fmt-text-writer.md
Specifically, the following changes were made:
* The contents of `fmt::rt` were all moved under `fmt::rt::v1`
* `fmt::rt` is stable
* `fmt::rt::v1` is stable
* `Error` is stable
* `Writer` is stable
* `Writer::write_str` is stable
* `Writer::write_fmt` is stable
* `Formatter` is stable
* `Argument` has been renamed to `ArgumentV1` and is stable
* `ArgumentV1::new` is stable
* `ArgumentV1::from_uint` is stable
* `Arguments::new_v1` is stable (renamed from `new`)
* `Arguments::new_v1_formatted` is stable (renamed from `with_placeholders`)
* All formatting traits are now stable, as well as the `fmt` method.
* `fmt::write` is stable
* `fmt::format` is stable
* `Formatter::pad_integral` is stable
* `Formatter::pad` is stable
* `Formatter::write_str` is stable
* `Formatter::write_fmt` is stable
* Some assorted top level items which were only used by `format_args!` were
removed in favor of static functions on `ArgumentV1` as well.
* The formatting-flag-accessing methods remain unstable
Within the contents of the `fmt::rt::v1` module, the following actions were
taken:
* Reexports of all enum variants were removed
* All prefixes on enum variants were removed
* A few miscellaneous enum variants were renamed
* Otherwise all structs, fields, and variants were marked stable.
In addition to these actions in the `std::fmt` module, many implementations of
`Show` and `String` were stabilized as well.
In some other modules:
* `ToString` is now stable
* `ToString::to_string` is now stable
* `Vec` no longer implements `fmt::Writer` (this has moved to `String`)
This is a breaking change due to all of the changes to the `fmt::rt` module, but
this likely will not have much impact on existing programs.
Closes #20661
[breaking-change]
2015-01-13 15:42:53 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-16 12:38:03 +11:00
|
|
|
|
fn to_string(&self) -> String;
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-26 19:42:11 +01:00
|
|
|
|
/// # Panics
|
|
|
|
|
///
|
|
|
|
|
/// In this implementation, the `to_string` method panics
|
|
|
|
|
/// if the `Display` implementation returns an error.
|
|
|
|
|
/// This indicates an incorrect `Display` implementation
|
|
|
|
|
/// since `fmt::Write for String` never returns an error itself.
|
std: Stabilize the std::fmt module
This commit performs a final stabilization pass over the std::fmt module,
marking all necessary APIs as stable. One of the more interesting aspects of
this module is that it exposes a good deal of its runtime representation to the
outside world in order for `format_args!` to be able to construct the format
strings. Instead of hacking the compiler to assume that these items are stable,
this commit instead lays out a story for the stabilization and evolution of
these APIs.
There are three primary details used by the `format_args!` macro:
1. `Arguments` - an opaque package of a "compiled format string". This structure
is passed around and the `write` function is the source of truth for
transforming a compiled format string into a string at runtime. This must be
able to be constructed in stable code.
2. `Argument` - an opaque structure representing an argument to a format string.
This is *almost* a trait object as it's just a pointer/function pair, but due
to the function originating from one of many traits, it's not actually a
trait object. Like `Arguments`, this must be constructed from stable code.
3. `fmt::rt` - this module contains the runtime type definitions primarily for
the `rt::Argument` structure. Whenever an argument is formatted with
nonstandard flags, a corresponding `rt::Argument` is generated describing how
the argument is being formatted. This can be used to construct an
`Arguments`.
The primary interface to `std::fmt` is the `Arguments` structure, and as such
this type name is stabilize as-is today. It is expected for libraries to pass
around an `Arguments` structure to represent a pending formatted computation.
The remaining portions are largely "cruft" which would rather not be stabilized,
but due to the stability checks they must be. As a result, almost all pieces
have been renamed to represent that they are "version 1" of the formatting
representation. The theory is that at a later date if we change the
representation of these types we can add new definitions called "version 2" and
corresponding constructors for `Arguments`.
One of the other remaining large questions about the fmt module were how the
pending I/O reform would affect the signatures of methods in the module. Due to
[RFC 526][rfc], however, the writers of fmt are now incompatible with the
writers of io, so this question has largely been solved. As a result the
interfaces are largely stabilized as-is today.
[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0526-fmt-text-writer.md
Specifically, the following changes were made:
* The contents of `fmt::rt` were all moved under `fmt::rt::v1`
* `fmt::rt` is stable
* `fmt::rt::v1` is stable
* `Error` is stable
* `Writer` is stable
* `Writer::write_str` is stable
* `Writer::write_fmt` is stable
* `Formatter` is stable
* `Argument` has been renamed to `ArgumentV1` and is stable
* `ArgumentV1::new` is stable
* `ArgumentV1::from_uint` is stable
* `Arguments::new_v1` is stable (renamed from `new`)
* `Arguments::new_v1_formatted` is stable (renamed from `with_placeholders`)
* All formatting traits are now stable, as well as the `fmt` method.
* `fmt::write` is stable
* `fmt::format` is stable
* `Formatter::pad_integral` is stable
* `Formatter::pad` is stable
* `Formatter::write_str` is stable
* `Formatter::write_fmt` is stable
* Some assorted top level items which were only used by `format_args!` were
removed in favor of static functions on `ArgumentV1` as well.
* The formatting-flag-accessing methods remain unstable
Within the contents of the `fmt::rt::v1` module, the following actions were
taken:
* Reexports of all enum variants were removed
* All prefixes on enum variants were removed
* A few miscellaneous enum variants were renamed
* Otherwise all structs, fields, and variants were marked stable.
In addition to these actions in the `std::fmt` module, many implementations of
`Show` and `String` were stabilized as well.
In some other modules:
* `ToString` is now stable
* `ToString::to_string` is now stable
* `Vec` no longer implements `fmt::Writer` (this has moved to `String`)
This is a breaking change due to all of the changes to the `fmt::rt` module, but
this likely will not have much impact on existing programs.
Closes #20661
[breaking-change]
2015-01-13 15:42:53 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-01-20 15:45:07 -08:00
|
|
|
|
impl<T: fmt::Display + ?Sized> ToString for T {
|
2015-01-10 11:07:14 +01:00
|
|
|
|
#[inline]
|
2016-03-22 19:29:56 -07:00
|
|
|
|
default fn to_string(&self) -> String {
|
2015-02-14 12:56:32 +13:00
|
|
|
|
use core::fmt::Write;
|
2014-12-20 00:09:35 -08:00
|
|
|
|
let mut buf = String::new();
|
2017-02-26 19:42:11 +01:00
|
|
|
|
buf.write_fmt(format_args!("{}", self))
|
|
|
|
|
.expect("a Display implementation return an error unexpectedly");
|
2014-12-20 00:09:35 -08:00
|
|
|
|
buf.shrink_to_fit();
|
|
|
|
|
buf
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-22 19:29:56 -07:00
|
|
|
|
#[stable(feature = "str_to_string_specialization", since = "1.9.0")]
|
|
|
|
|
impl ToString for str {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_string(&self) -> String {
|
|
|
|
|
String::from(self)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-01 11:54:36 +08:00
|
|
|
|
#[stable(feature = "cow_str_to_string_specialization", since = "1.17.0")]
|
|
|
|
|
impl<'a> ToString for Cow<'a, str> {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_string(&self) -> String {
|
|
|
|
|
self[..].to_owned()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "string_to_string_specialization", since = "1.17.0")]
|
|
|
|
|
impl ToString for String {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_string(&self) -> String {
|
|
|
|
|
self.to_owned()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-18 09:14:54 -07:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl AsRef<str> for String {
|
2015-05-10 14:06:41 +02:00
|
|
|
|
#[inline]
|
2015-03-18 09:14:54 -07:00
|
|
|
|
fn as_ref(&self) -> &str {
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-06 15:53:53 -07:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl AsRef<[u8]> for String {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn as_ref(&self) -> &[u8] {
|
|
|
|
|
self.as_bytes()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-18 09:14:54 -07:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl<'a> From<&'a str> for String {
|
|
|
|
|
fn from(s: &'a str) -> String {
|
2016-03-10 21:15:29 +01:00
|
|
|
|
s.to_owned()
|
2015-03-18 09:14:54 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-13 20:37:42 -05:00
|
|
|
|
// note: test pulls in libstd, which causes errors here
|
|
|
|
|
#[cfg(not(test))]
|
2017-05-20 08:38:39 +01:00
|
|
|
|
#[stable(feature = "string_from_box", since = "1.18.0")]
|
2017-02-13 20:37:42 -05:00
|
|
|
|
impl From<Box<str>> for String {
|
|
|
|
|
fn from(s: Box<str>) -> String {
|
|
|
|
|
s.into_string()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-13 00:08:37 +01:00
|
|
|
|
#[stable(feature = "box_from_str", since = "1.20.0")]
|
2017-05-20 15:40:53 -04:00
|
|
|
|
impl From<String> for Box<str> {
|
|
|
|
|
fn from(s: String) -> Box<str> {
|
|
|
|
|
s.into_boxed_str()
|
2017-02-13 20:37:42 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Implement `From<Cow<str>> for String` and `From<Cow<[T]>> for Vec<T>`.
Motivation: the `selectors` crate is generic over a string type,
in order to support all of `String`, `string_cache::Atom`, and
`gecko_string_cache::Atom`. Multiple trait bounds are used
for the various operations done with these strings.
One of these operations is creating a string (as efficiently as possible,
re-using an existing memory allocation if possible) from `Cow<str>`.
The `std::convert::From` trait seems natural for this, but
the relevant implementation was missing before this PR.
To work around this I’ve added a `FromCowStr` trait in `selectors`,
but with trait coherence that means one of `selectors` or `string_cache`
needs to depend on the other to implement this trait.
Using a trait from `std` would solve this.
The `Vec<T>` implementation is just added for consistency.
I also tried a more general
`impl<'a, O, B: ?Sized + ToOwned<Owned=O>> From<Cow<'a, B>> for O`,
but (the compiler thinks?) it conflicts with `From<T> for T` the impl
(after moving all of `collections::borrow` into `core::borrow`
to work around trait coherence).
2016-10-21 16:51:59 +02:00
|
|
|
|
#[stable(feature = "string_from_cow_str", since = "1.14.0")]
|
|
|
|
|
impl<'a> From<Cow<'a, str>> for String {
|
|
|
|
|
fn from(s: Cow<'a, str>) -> String {
|
|
|
|
|
s.into_owned()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-30 12:07:16 -07:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl<'a> From<&'a str> for Cow<'a, str> {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn from(s: &'a str) -> Cow<'a, str> {
|
|
|
|
|
Cow::Borrowed(s)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
|
impl<'a> From<String> for Cow<'a, str> {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn from(s: String) -> Cow<'a, str> {
|
|
|
|
|
Cow::Owned(s)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-26 21:16:46 -07:00
|
|
|
|
#[stable(feature = "cow_str_from_iter", since = "1.12.0")]
|
|
|
|
|
impl<'a> FromIterator<char> for Cow<'a, str> {
|
|
|
|
|
fn from_iter<I: IntoIterator<Item = char>>(it: I) -> Cow<'a, str> {
|
|
|
|
|
Cow::Owned(FromIterator::from_iter(it))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "cow_str_from_iter", since = "1.12.0")]
|
|
|
|
|
impl<'a, 'b> FromIterator<&'b str> for Cow<'a, str> {
|
|
|
|
|
fn from_iter<I: IntoIterator<Item = &'b str>>(it: I) -> Cow<'a, str> {
|
|
|
|
|
Cow::Owned(FromIterator::from_iter(it))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[stable(feature = "cow_str_from_iter", since = "1.12.0")]
|
|
|
|
|
impl<'a> FromIterator<String> for Cow<'a, str> {
|
|
|
|
|
fn from_iter<I: IntoIterator<Item = String>>(it: I) -> Cow<'a, str> {
|
|
|
|
|
Cow::Owned(FromIterator::from_iter(it))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-04 15:54:08 -02:00
|
|
|
|
#[stable(feature = "from_string_for_vec_u8", since = "1.14.0")]
|
|
|
|
|
impl From<String> for Vec<u8> {
|
2016-12-20 09:54:00 +05:30
|
|
|
|
fn from(string: String) -> Vec<u8> {
|
2016-11-04 15:54:08 -02:00
|
|
|
|
string.into_bytes()
|
2015-03-18 09:14:54 -07:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
std: Stabilize the std::fmt module
This commit performs a final stabilization pass over the std::fmt module,
marking all necessary APIs as stable. One of the more interesting aspects of
this module is that it exposes a good deal of its runtime representation to the
outside world in order for `format_args!` to be able to construct the format
strings. Instead of hacking the compiler to assume that these items are stable,
this commit instead lays out a story for the stabilization and evolution of
these APIs.
There are three primary details used by the `format_args!` macro:
1. `Arguments` - an opaque package of a "compiled format string". This structure
is passed around and the `write` function is the source of truth for
transforming a compiled format string into a string at runtime. This must be
able to be constructed in stable code.
2. `Argument` - an opaque structure representing an argument to a format string.
This is *almost* a trait object as it's just a pointer/function pair, but due
to the function originating from one of many traits, it's not actually a
trait object. Like `Arguments`, this must be constructed from stable code.
3. `fmt::rt` - this module contains the runtime type definitions primarily for
the `rt::Argument` structure. Whenever an argument is formatted with
nonstandard flags, a corresponding `rt::Argument` is generated describing how
the argument is being formatted. This can be used to construct an
`Arguments`.
The primary interface to `std::fmt` is the `Arguments` structure, and as such
this type name is stabilize as-is today. It is expected for libraries to pass
around an `Arguments` structure to represent a pending formatted computation.
The remaining portions are largely "cruft" which would rather not be stabilized,
but due to the stability checks they must be. As a result, almost all pieces
have been renamed to represent that they are "version 1" of the formatting
representation. The theory is that at a later date if we change the
representation of these types we can add new definitions called "version 2" and
corresponding constructors for `Arguments`.
One of the other remaining large questions about the fmt module were how the
pending I/O reform would affect the signatures of methods in the module. Due to
[RFC 526][rfc], however, the writers of fmt are now incompatible with the
writers of io, so this question has largely been solved. As a result the
interfaces are largely stabilized as-is today.
[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/0526-fmt-text-writer.md
Specifically, the following changes were made:
* The contents of `fmt::rt` were all moved under `fmt::rt::v1`
* `fmt::rt` is stable
* `fmt::rt::v1` is stable
* `Error` is stable
* `Writer` is stable
* `Writer::write_str` is stable
* `Writer::write_fmt` is stable
* `Formatter` is stable
* `Argument` has been renamed to `ArgumentV1` and is stable
* `ArgumentV1::new` is stable
* `ArgumentV1::from_uint` is stable
* `Arguments::new_v1` is stable (renamed from `new`)
* `Arguments::new_v1_formatted` is stable (renamed from `with_placeholders`)
* All formatting traits are now stable, as well as the `fmt` method.
* `fmt::write` is stable
* `fmt::format` is stable
* `Formatter::pad_integral` is stable
* `Formatter::pad` is stable
* `Formatter::write_str` is stable
* `Formatter::write_fmt` is stable
* Some assorted top level items which were only used by `format_args!` were
removed in favor of static functions on `ArgumentV1` as well.
* The formatting-flag-accessing methods remain unstable
Within the contents of the `fmt::rt::v1` module, the following actions were
taken:
* Reexports of all enum variants were removed
* All prefixes on enum variants were removed
* A few miscellaneous enum variants were renamed
* Otherwise all structs, fields, and variants were marked stable.
In addition to these actions in the `std::fmt` module, many implementations of
`Show` and `String` were stabilized as well.
In some other modules:
* `ToString` is now stable
* `ToString::to_string` is now stable
* `Vec` no longer implements `fmt::Writer` (this has moved to `String`)
This is a breaking change due to all of the changes to the `fmt::rt` module, but
this likely will not have much impact on existing programs.
Closes #20661
[breaking-change]
2015-01-13 15:42:53 -08:00
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2015-02-14 12:56:32 +13:00
|
|
|
|
impl fmt::Write for String {
|
2015-01-10 11:07:14 +01:00
|
|
|
|
#[inline]
|
2014-12-12 10:59:41 -08:00
|
|
|
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
|
|
|
|
self.push_str(s);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2015-04-21 14:51:28 +02:00
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn write_char(&mut self, c: char) -> fmt::Result {
|
|
|
|
|
self.push(c);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2014-12-12 10:59:41 -08:00
|
|
|
|
}
|
2015-05-01 15:34:25 +02:00
|
|
|
|
|
|
|
|
|
/// A draining iterator for `String`.
|
2016-02-09 12:02:55 -05:00
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// This struct is created by the [`drain`] method on [`String`]. See its
|
2016-02-09 12:02:55 -05:00
|
|
|
|
/// documentation for more.
|
|
|
|
|
///
|
2017-03-12 14:04:52 -04:00
|
|
|
|
/// [`drain`]: struct.String.html#method.drain
|
2016-02-09 12:02:55 -05:00
|
|
|
|
/// [`String`]: struct.String.html
|
2015-12-02 17:31:49 -08:00
|
|
|
|
#[stable(feature = "drain", since = "1.6.0")]
|
2015-05-01 15:34:25 +02:00
|
|
|
|
pub struct Drain<'a> {
|
|
|
|
|
/// Will be used as &'a mut String in the destructor
|
|
|
|
|
string: *mut String,
|
|
|
|
|
/// Start of part to remove
|
|
|
|
|
start: usize,
|
|
|
|
|
/// End of part to remove
|
|
|
|
|
end: usize,
|
|
|
|
|
/// Current remaining range to remove
|
|
|
|
|
iter: Chars<'a>,
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-21 00:33:38 +01:00
|
|
|
|
#[stable(feature = "collection_debug", since = "1.17.0")]
|
2017-01-11 23:12:49 +01:00
|
|
|
|
impl<'a> fmt::Debug for Drain<'a> {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2017-01-21 00:33:38 +01:00
|
|
|
|
f.pad("Drain { .. }")
|
2017-01-11 23:12:49 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
|
#[stable(feature = "drain", since = "1.6.0")]
|
2015-05-01 15:34:25 +02:00
|
|
|
|
unsafe impl<'a> Sync for Drain<'a> {}
|
2015-12-02 17:31:49 -08:00
|
|
|
|
#[stable(feature = "drain", since = "1.6.0")]
|
2015-05-01 15:34:25 +02:00
|
|
|
|
unsafe impl<'a> Send for Drain<'a> {}
|
|
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
|
#[stable(feature = "drain", since = "1.6.0")]
|
2015-05-01 15:34:25 +02:00
|
|
|
|
impl<'a> Drop for Drain<'a> {
|
|
|
|
|
fn drop(&mut self) {
|
|
|
|
|
unsafe {
|
|
|
|
|
// Use Vec::drain. "Reaffirm" the bounds checks to avoid
|
|
|
|
|
// panic code being inserted again.
|
|
|
|
|
let self_vec = (*self.string).as_mut_vec();
|
|
|
|
|
if self.start <= self.end && self.end <= self_vec.len() {
|
|
|
|
|
self_vec.drain(self.start..self.end);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
|
#[stable(feature = "drain", since = "1.6.0")]
|
2015-05-01 15:34:25 +02:00
|
|
|
|
impl<'a> Iterator for Drain<'a> {
|
|
|
|
|
type Item = char;
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn next(&mut self) -> Option<char> {
|
|
|
|
|
self.iter.next()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
|
|
|
self.iter.size_hint()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-02 17:31:49 -08:00
|
|
|
|
#[stable(feature = "drain", since = "1.6.0")]
|
2015-05-01 15:34:25 +02:00
|
|
|
|
impl<'a> DoubleEndedIterator for Drain<'a> {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn next_back(&mut self) -> Option<char> {
|
|
|
|
|
self.iter.next_back()
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-08-13 14:42:36 -04:00
|
|
|
|
|
2018-03-03 14:15:28 +01:00
|
|
|
|
#[stable(feature = "fused", since = "1.26.0")]
|
2016-08-13 14:42:36 -04:00
|
|
|
|
impl<'a> FusedIterator for Drain<'a> {}
|