string.rs 42.9 KB
Newer Older
1 2 3 4 5 6 7 8 9
// 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.
10 11
//
// ignore-lexer-test FIXME #15679
12 13 14

//! An owned, growable string that enforces that its contents are valid UTF-8.

B
Brian Anderson 已提交
15
#![stable(feature = "rust1", since = "1.0.0")]
16

17 18 19
use core::prelude::*;

use core::default::Default;
20
use core::error::Error;
21
use core::fmt;
22
use core::hash;
A
Alexis 已提交
23
use core::iter::{IntoIterator, FromIterator};
24
use core::mem;
N
fallout  
Nick Cameron 已提交
25
use core::ops::{self, Deref, Add, Index};
26
use core::ptr;
27
use core::raw::Slice as RawSlice;
A
Alex Crichton 已提交
28 29
use unicode::str as unicode_str;
use unicode::str::Utf16Item;
30

A
Aaron Turon 已提交
31
use borrow::{Cow, IntoCow};
32
use str::{self, CharRange, FromStr, Utf8Error};
33
use vec::{DerefVec, Vec, as_vec};
34

35
/// A growable string stored as a UTF-8 encoded buffer.
36
#[derive(Clone, PartialOrd, Eq, Ord)]
B
Brian Anderson 已提交
37
#[stable(feature = "rust1", since = "1.0.0")]
38
pub struct String {
39 40 41
    vec: Vec<u8>,
}

42
/// A possible error value from the `String::from_utf8` function.
B
Brian Anderson 已提交
43
#[stable(feature = "rust1", since = "1.0.0")]
J
Jorge Aparicio 已提交
44
#[derive(Debug)]
45 46 47 48 49 50
pub struct FromUtf8Error {
    bytes: Vec<u8>,
    error: Utf8Error,
}

/// A possible error value from the `String::from_utf16` function.
B
Brian Anderson 已提交
51
#[stable(feature = "rust1", since = "1.0.0")]
J
Jorge Aparicio 已提交
52
#[derive(Debug)]
53 54
pub struct FromUtf16Error(());

55
impl String {
J
Joseph Crail 已提交
56
    /// Creates a new string buffer initialized with the empty string.
J
Jonas Hietala 已提交
57
    ///
58
    /// # Examples
J
Jonas Hietala 已提交
59 60 61 62
    ///
    /// ```
    /// let mut s = String::new();
    /// ```
63
    #[inline]
B
Brian Anderson 已提交
64
    #[stable(feature = "rust1", since = "1.0.0")]
65 66
    pub fn new() -> String {
        String {
67 68 69 70 71
            vec: Vec::new(),
        }
    }

    /// Creates a new string buffer with the given capacity.
J
Jonas Hietala 已提交
72 73 74
    /// The string will be able to hold exactly `capacity` bytes without
    /// reallocating. If `capacity` is 0, the string will not allocate.
    ///
75
    /// # Examples
J
Jonas Hietala 已提交
76 77 78 79
    ///
    /// ```
    /// let mut s = String::with_capacity(10);
    /// ```
80
    #[inline]
B
Brian Anderson 已提交
81
    #[stable(feature = "rust1", since = "1.0.0")]
A
Alexis 已提交
82
    pub fn with_capacity(capacity: usize) -> String {
83
        String {
84 85 86 87 88
            vec: Vec::with_capacity(capacity),
        }
    }

    /// Creates a new string buffer from the given string.
J
Jonas Hietala 已提交
89
    ///
90
    /// # Examples
J
Jonas Hietala 已提交
91 92 93 94 95
    ///
    /// ```
    /// let s = String::from_str("hello");
    /// assert_eq!(s.as_slice(), "hello");
    /// ```
96
    #[inline]
97
    #[unstable(feature = "collections",
98
               reason = "needs investigation to see if to_string() can match perf")]
99
    pub fn from_str(string: &str) -> String {
100
        String { vec: ::slice::SliceExt::to_vec(string.as_bytes()) }
101 102
    }

103 104 105
    /// Returns the vector as a string buffer, if possible, taking care not to
    /// copy it.
    ///
A
Alex Crichton 已提交
106 107 108 109
    /// # Failure
    ///
    /// If the given vector is not valid UTF-8, then the original vector and the
    /// corresponding error is returned.
110
    ///
111
    /// # Examples
112 113
    ///
    /// ```rust
A
Alex Crichton 已提交
114 115
    /// use std::str::Utf8Error;
    ///
116
    /// let hello_vec = vec![104, 101, 108, 108, 111];
117 118
    /// let s = String::from_utf8(hello_vec).unwrap();
    /// assert_eq!(s, "hello");
J
Jonas Hietala 已提交
119 120
    ///
    /// let invalid_vec = vec![240, 144, 128];
121 122 123
    /// let s = String::from_utf8(invalid_vec).err().unwrap();
    /// assert_eq!(s.utf8_error(), Utf8Error::TooShort);
    /// assert_eq!(s.into_bytes(), vec![240, 144, 128]);
124
    /// ```
125
    #[inline]
B
Brian Anderson 已提交
126
    #[stable(feature = "rust1", since = "1.0.0")]
127
    pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> {
128
        match str::from_utf8(&vec) {
A
Alex Crichton 已提交
129
            Ok(..) => Ok(String { vec: vec }),
130
            Err(e) => Err(FromUtf8Error { bytes: vec, error: e })
131 132
        }
    }
133

P
P1start 已提交
134 135
    /// Converts a vector of bytes to a new UTF-8 string.
    /// Any invalid UTF-8 sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
136
    ///
137
    /// # Examples
138 139 140
    ///
    /// ```rust
    /// let input = b"Hello \xF0\x90\x80World";
A
Adolfo Ochagavía 已提交
141
    /// let output = String::from_utf8_lossy(input);
A
Alex Crichton 已提交
142
    /// assert_eq!(output.as_slice(), "Hello \u{FFFD}World");
143
    /// ```
B
Brian Anderson 已提交
144
    #[stable(feature = "rust1", since = "1.0.0")]
A
Aaron Turon 已提交
145
    pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str> {
146
        let mut i = 0;
A
Alex Crichton 已提交
147 148
        match str::from_utf8(v) {
            Ok(s) => return Cow::Borrowed(s),
149 150 151 152 153
            Err(e) => {
                if let Utf8Error::InvalidByte(firstbad) = e {
                    i = firstbad;
                }
            }
154 155 156 157 158
        }

        static TAG_CONT_U8: u8 = 128u8;
        static REPLACEMENT: &'static [u8] = b"\xEF\xBF\xBD"; // U+FFFD in UTF-8
        let total = v.len();
A
Alexis 已提交
159
        fn unsafe_get(xs: &[u8], i: usize) -> u8 {
A
Aaron Turon 已提交
160
            unsafe { *xs.get_unchecked(i) }
161
        }
A
Alexis 已提交
162
        fn safe_get(xs: &[u8], i: usize, total: usize) -> u8 {
163 164 165 166 167 168 169 170 171 172 173
            if i >= total {
                0
            } else {
                unsafe_get(xs, i)
            }
        }

        let mut res = String::with_capacity(total);

        if i > 0 {
            unsafe {
174
                res.as_mut_vec().push_all(&v[..i])
175 176 177 178 179 180
            };
        }

        // subseqidx is the index of the first byte of the subsequence we're looking at.
        // It's used to copy a bunch of contiguous good codepoints at once instead of copying
        // them one by one.
181
        let mut subseqidx = i;
182 183 184 185 186 187

        while i < total {
            let i_ = i;
            let byte = unsafe_get(v, i);
            i += 1;

188
            macro_rules! error { () => ({
189 190
                unsafe {
                    if subseqidx != i_ {
J
Jorge Aparicio 已提交
191
                        res.as_mut_vec().push_all(&v[subseqidx..i_]);
192 193
                    }
                    subseqidx = i;
194
                    res.as_mut_vec().push_all(REPLACEMENT);
195
                }
196
            })}
197 198 199 200

            if byte < 128u8 {
                // subseqidx handles this
            } else {
A
Alex Crichton 已提交
201
                let w = unicode_str::utf8_char_width(byte);
202 203 204 205 206 207 208 209 210 211 212

                match w {
                    2 => {
                        if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
                            error!();
                            continue;
                        }
                        i += 1;
                    }
                    3 => {
                        match (byte, safe_get(v, i, total)) {
213 214 215 216
                            (0xE0         , 0xA0 ... 0xBF) => (),
                            (0xE1 ... 0xEC, 0x80 ... 0xBF) => (),
                            (0xED         , 0x80 ... 0x9F) => (),
                            (0xEE ... 0xEF, 0x80 ... 0xBF) => (),
217 218 219 220 221 222 223 224 225 226 227 228 229 230
                            _ => {
                                error!();
                                continue;
                            }
                        }
                        i += 1;
                        if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
                            error!();
                            continue;
                        }
                        i += 1;
                    }
                    4 => {
                        match (byte, safe_get(v, i, total)) {
231 232 233
                            (0xF0         , 0x90 ... 0xBF) => (),
                            (0xF1 ... 0xF3, 0x80 ... 0xBF) => (),
                            (0xF4         , 0x80 ... 0x8F) => (),
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
                            _ => {
                                error!();
                                continue;
                            }
                        }
                        i += 1;
                        if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
                            error!();
                            continue;
                        }
                        i += 1;
                        if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
                            error!();
                            continue;
                        }
                        i += 1;
                    }
                    _ => {
                        error!();
                        continue;
                    }
                }
            }
        }
        if subseqidx < total {
            unsafe {
J
Jorge Aparicio 已提交
260
                res.as_mut_vec().push_all(&v[subseqidx..total])
261 262
            };
        }
A
Alex Crichton 已提交
263
        Cow::Owned(res)
264 265
    }

A
Adolfo Ochagavía 已提交
266
    /// Decode a UTF-16 encoded vector `v` into a `String`, returning `None`
A
Adolfo Ochagavía 已提交
267 268
    /// if `v` contains any invalid data.
    ///
269
    /// # Examples
A
Adolfo Ochagavía 已提交
270 271
    ///
    /// ```rust
A
Adolfo Ochagavía 已提交
272
    /// // 𝄞music
N
Nick Cameron 已提交
273 274
    /// let mut v = &mut [0xD834, 0xDD1E, 0x006d, 0x0075,
    ///                   0x0073, 0x0069, 0x0063];
275 276
    /// assert_eq!(String::from_utf16(v).unwrap(),
    ///            "𝄞music".to_string());
A
Adolfo Ochagavía 已提交
277
    ///
A
Adolfo Ochagavía 已提交
278
    /// // 𝄞mu<invalid>ic
A
Adolfo Ochagavía 已提交
279
    /// v[4] = 0xD800;
280
    /// assert!(String::from_utf16(v).is_err());
A
Adolfo Ochagavía 已提交
281
    /// ```
B
Brian Anderson 已提交
282
    #[stable(feature = "rust1", since = "1.0.0")]
283
    pub fn from_utf16(v: &[u16]) -> Result<String, FromUtf16Error> {
284
        let mut s = String::with_capacity(v.len());
A
Alex Crichton 已提交
285
        for c in unicode_str::utf16_items(v) {
A
Adolfo Ochagavía 已提交
286
            match c {
A
Alex Crichton 已提交
287
                Utf16Item::ScalarValue(c) => s.push(c),
288
                Utf16Item::LoneSurrogate(_) => return Err(FromUtf16Error(())),
A
Adolfo Ochagavía 已提交
289 290
            }
        }
291
        Ok(s)
A
Adolfo Ochagavía 已提交
292
    }
293

294 295 296
    /// Decode a UTF-16 encoded vector `v` into a string, replacing
    /// invalid data with the replacement character (U+FFFD).
    ///
297 298
    /// # Examples
    ///
299
    /// ```rust
A
Adolfo Ochagavía 已提交
300
    /// // 𝄞mus<invalid>ic<invalid>
N
Nick Cameron 已提交
301 302 303
    /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
    ///           0x0073, 0xDD1E, 0x0069, 0x0063,
    ///           0xD834];
304 305
    ///
    /// assert_eq!(String::from_utf16_lossy(v),
A
Alex Crichton 已提交
306
    ///            "𝄞mus\u{FFFD}ic\u{FFFD}".to_string());
307
    /// ```
308
    #[inline]
B
Brian Anderson 已提交
309
    #[stable(feature = "rust1", since = "1.0.0")]
310
    pub fn from_utf16_lossy(v: &[u16]) -> String {
A
Alex Crichton 已提交
311
        unicode_str::utf16_items(v).map(|c| c.to_char_lossy()).collect()
312
    }
A
Adolfo Ochagavía 已提交
313

314 315 316 317 318 319
    /// Creates a new `String` from a length, capacity, and pointer.
    ///
    /// This is unsafe because:
    /// * We call `Vec::from_raw_parts` to get a `Vec<u8>`;
    /// * We assume that the `Vec` contains valid UTF-8.
    #[inline]
B
Brian Anderson 已提交
320
    #[stable(feature = "rust1", since = "1.0.0")]
A
Alexis 已提交
321
    pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String {
322 323 324 325 326 327 328 329 330
        String {
            vec: Vec::from_raw_parts(buf, length, capacity),
        }
    }

    /// Converts a vector of bytes to a new `String` without checking if
    /// it contains valid UTF-8. This is unsafe because it assumes that
    /// the UTF-8-ness of the vector has already been validated.
    #[inline]
B
Brian Anderson 已提交
331
    #[stable(feature = "rust1", since = "1.0.0")]
332 333 334 335
    pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String {
        String { vec: bytes }
    }

336
    /// Return the underlying byte buffer, encoded as UTF-8.
J
Jonas Hietala 已提交
337
    ///
338
    /// # Examples
J
Jonas Hietala 已提交
339 340 341 342 343 344
    ///
    /// ```
    /// let s = String::from_str("hello");
    /// let bytes = s.into_bytes();
    /// assert_eq!(bytes, vec![104, 101, 108, 108, 111]);
    /// ```
345
    #[inline]
B
Brian Anderson 已提交
346
    #[stable(feature = "rust1", since = "1.0.0")]
347 348 349 350
    pub fn into_bytes(self) -> Vec<u8> {
        self.vec
    }

351
    /// Pushes the given string onto this string buffer.
J
Jonas Hietala 已提交
352
    ///
353
    /// # Examples
J
Jonas Hietala 已提交
354 355 356 357 358 359
    ///
    /// ```
    /// let mut s = String::from_str("foo");
    /// s.push_str("bar");
    /// assert_eq!(s.as_slice(), "foobar");
    /// ```
360
    #[inline]
B
Brian Anderson 已提交
361
    #[stable(feature = "rust1", since = "1.0.0")]
362 363 364 365
    pub fn push_str(&mut self, string: &str) {
        self.vec.push_all(string.as_bytes())
    }

366 367
    /// Returns the number of bytes that this string buffer can hold without
    /// reallocating.
A
Alex Crichton 已提交
368
    ///
369
    /// # Examples
A
Alex Crichton 已提交
370 371 372
    ///
    /// ```
    /// let s = String::with_capacity(10);
373
    /// assert!(s.capacity() >= 10);
A
Alex Crichton 已提交
374 375
    /// ```
    #[inline]
B
Brian Anderson 已提交
376
    #[stable(feature = "rust1", since = "1.0.0")]
A
Alexis 已提交
377
    pub fn capacity(&self) -> usize {
A
Alex Crichton 已提交
378 379 380
        self.vec.capacity()
    }

381 382 383
    /// Reserves capacity for at least `additional` more bytes to be inserted
    /// in the given `String`. The collection may reserve more space to avoid
    /// frequent reallocations.
384 385 386
    ///
    /// # Panics
    ///
A
Alexis 已提交
387
    /// Panics if the new capacity overflows `usize`.
J
Jonas Hietala 已提交
388
    ///
389
    /// # Examples
J
Jonas Hietala 已提交
390 391 392 393
    ///
    /// ```
    /// let mut s = String::new();
    /// s.reserve(10);
394
    /// assert!(s.capacity() >= 10);
J
Jonas Hietala 已提交
395
    /// ```
396
    #[inline]
B
Brian Anderson 已提交
397
    #[stable(feature = "rust1", since = "1.0.0")]
A
Alexis 已提交
398
    pub fn reserve(&mut self, additional: usize) {
399
        self.vec.reserve(additional)
400 401
    }

402 403 404
    /// Reserves the minimum capacity for exactly `additional` more bytes to be
    /// inserted in the given `String`. Does nothing if the capacity is already
    /// sufficient.
405
    ///
406 407 408
    /// 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.
409 410 411
    ///
    /// # Panics
    ///
A
Alexis 已提交
412
    /// Panics if the new capacity overflows `usize`.
J
Jonas Hietala 已提交
413
    ///
414
    /// # Examples
J
Jonas Hietala 已提交
415 416 417
    ///
    /// ```
    /// let mut s = String::new();
418 419
    /// s.reserve(10);
    /// assert!(s.capacity() >= 10);
J
Jonas Hietala 已提交
420
    /// ```
421
    #[inline]
B
Brian Anderson 已提交
422
    #[stable(feature = "rust1", since = "1.0.0")]
A
Alexis 已提交
423
    pub fn reserve_exact(&mut self, additional: usize) {
424
        self.vec.reserve_exact(additional)
425 426 427
    }

    /// Shrinks the capacity of this string buffer to match its length.
J
Jonas Hietala 已提交
428
    ///
429
    /// # Examples
J
Jonas Hietala 已提交
430 431 432 433
    ///
    /// ```
    /// let mut s = String::from_str("foo");
    /// s.reserve(100);
434
    /// assert!(s.capacity() >= 100);
J
Jonas Hietala 已提交
435
    /// s.shrink_to_fit();
436
    /// assert_eq!(s.capacity(), 3);
J
Jonas Hietala 已提交
437
    /// ```
438
    #[inline]
B
Brian Anderson 已提交
439
    #[stable(feature = "rust1", since = "1.0.0")]
440 441 442 443 444
    pub fn shrink_to_fit(&mut self) {
        self.vec.shrink_to_fit()
    }

    /// Adds the given character to the end of the string.
J
Jonas Hietala 已提交
445
    ///
446
    /// # Examples
J
Jonas Hietala 已提交
447 448 449
    ///
    /// ```
    /// let mut s = String::from_str("abc");
A
Alex Crichton 已提交
450 451 452
    /// s.push('1');
    /// s.push('2');
    /// s.push('3');
J
Jonas Hietala 已提交
453 454
    /// assert_eq!(s.as_slice(), "abc123");
    /// ```
455
    #[inline]
B
Brian Anderson 已提交
456
    #[stable(feature = "rust1", since = "1.0.0")]
A
Alex Crichton 已提交
457
    pub fn push(&mut self, ch: char) {
458 459 460 461 462
        if (ch as u32) < 0x80 {
            self.vec.push(ch as u8);
            return;
        }

463
        let cur_len = self.len();
464
        // This may use up to 4 bytes.
465
        self.vec.reserve(4);
466

467
        unsafe {
468 469
            // Attempt to not use an intermediate buffer by just pushing bytes
            // directly onto this string.
470
            let slice = RawSlice {
471
                data: self.vec.as_ptr().offset(cur_len as isize),
472 473
                len: 4,
            };
474
            let used = ch.encode_utf8(mem::transmute(slice)).unwrap_or(0);
475 476 477 478 479
            self.vec.set_len(cur_len + used);
        }
    }

    /// Works with the underlying buffer as a byte slice.
J
Jonas Hietala 已提交
480
    ///
481
    /// # Examples
J
Jonas Hietala 已提交
482 483 484
    ///
    /// ```
    /// let s = String::from_str("hello");
N
Nick Cameron 已提交
485 486
    /// let b: &[_] = &[104, 101, 108, 108, 111];
    /// assert_eq!(s.as_bytes(), b);
J
Jonas Hietala 已提交
487
    /// ```
488
    #[inline]
B
Brian Anderson 已提交
489
    #[stable(feature = "rust1", since = "1.0.0")]
490
    pub fn as_bytes(&self) -> &[u8] {
491
        &self.vec
492 493
    }

P
P1start 已提交
494
    /// Shortens a string to the specified length.
J
Jonas Hietala 已提交
495
    ///
496
    /// # Panics
J
Jonas Hietala 已提交
497
    ///
498
    /// Panics if `new_len` > current length,
499
    /// or if `new_len` is not a character boundary.
J
Jonas Hietala 已提交
500
    ///
501
    /// # Examples
J
Jonas Hietala 已提交
502 503 504 505 506 507
    ///
    /// ```
    /// let mut s = String::from_str("hello");
    /// s.truncate(2);
    /// assert_eq!(s.as_slice(), "he");
    /// ```
508
    #[inline]
B
Brian Anderson 已提交
509
    #[stable(feature = "rust1", since = "1.0.0")]
A
Alexis 已提交
510
    pub fn truncate(&mut self, new_len: usize) {
511
        assert!(self.is_char_boundary(new_len));
512
        self.vec.truncate(new_len)
513 514
    }

J
Jonas Hietala 已提交
515 516 517
    /// Removes the last character from the string buffer and returns it.
    /// Returns `None` if this string buffer is empty.
    ///
518
    /// # Examples
J
Jonas Hietala 已提交
519 520 521
    ///
    /// ```
    /// let mut s = String::from_str("foo");
A
Alex Crichton 已提交
522 523 524 525
    /// assert_eq!(s.pop(), Some('o'));
    /// assert_eq!(s.pop(), Some('o'));
    /// assert_eq!(s.pop(), Some('f'));
    /// assert_eq!(s.pop(), None);
J
Jonas Hietala 已提交
526
    /// ```
527
    #[inline]
B
Brian Anderson 已提交
528
    #[stable(feature = "rust1", since = "1.0.0")]
A
Alex Crichton 已提交
529
    pub fn pop(&mut self) -> Option<char> {
530 531 532 533 534
        let len = self.len();
        if len == 0 {
            return None
        }

535
        let CharRange {ch, next} = self.char_range_at_reverse(len);
536 537 538 539 540 541
        unsafe {
            self.vec.set_len(next);
        }
        Some(ch)
    }

542
    /// Removes the character from the string buffer at byte position `idx` and
543
    /// returns it.
544 545 546
    ///
    /// # Warning
    ///
547
    /// This is an O(n) operation as it requires copying every element in the
548 549
    /// buffer.
    ///
S
Steve Klabnik 已提交
550
    /// # Panics
551
    ///
552 553
    /// If `idx` does not lie on a character boundary, or if it is out of
    /// bounds, then this function will panic.
J
Jonas Hietala 已提交
554
    ///
555
    /// # Examples
J
Jonas Hietala 已提交
556 557 558
    ///
    /// ```
    /// let mut s = String::from_str("foo");
559 560 561
    /// assert_eq!(s.remove(0), 'f');
    /// assert_eq!(s.remove(1), 'o');
    /// assert_eq!(s.remove(0), 'o');
J
Jonas Hietala 已提交
562
    /// ```
563
    #[inline]
B
Brian Anderson 已提交
564
    #[stable(feature = "rust1", since = "1.0.0")]
A
Alexis 已提交
565
    pub fn remove(&mut self, idx: usize) -> char {
566
        let len = self.len();
567
        assert!(idx <= len);
568

569
        let CharRange { ch, next } = self.char_range_at(idx);
570
        unsafe {
571 572
            ptr::copy_memory(self.vec.as_mut_ptr().offset(idx as isize),
                             self.vec.as_ptr().offset(next as isize),
573 574
                             len - next);
            self.vec.set_len(len - (next - idx));
575
        }
576
        ch
577
    }
578

579 580 581 582
    /// Insert a character into the string buffer at byte position `idx`.
    ///
    /// # Warning
    ///
583
    /// This is an O(n) operation as it requires copying every element in the
584 585
    /// buffer.
    ///
S
Steve Klabnik 已提交
586
    /// # Panics
587 588
    ///
    /// If `idx` does not lie on a character boundary or is out of bounds, then
S
Steve Klabnik 已提交
589
    /// this function will panic.
590
    #[inline]
B
Brian Anderson 已提交
591
    #[stable(feature = "rust1", since = "1.0.0")]
A
Alexis 已提交
592
    pub fn insert(&mut self, idx: usize, ch: char) {
593 594
        let len = self.len();
        assert!(idx <= len);
595
        assert!(self.is_char_boundary(idx));
596
        self.vec.reserve(4);
597
        let mut bits = [0; 4];
N
Nick Cameron 已提交
598
        let amt = ch.encode_utf8(&mut bits).unwrap();
599 600

        unsafe {
601 602
            ptr::copy_memory(self.vec.as_mut_ptr().offset((idx + amt) as isize),
                             self.vec.as_ptr().offset(idx as isize),
603
                             len - idx);
604
            ptr::copy_memory(self.vec.as_mut_ptr().offset(idx as isize),
605 606 607 608 609 610
                             bits.as_ptr(),
                             amt);
            self.vec.set_len(len + amt);
        }
    }

611 612
    /// Views the string buffer as a mutable sequence of bytes.
    ///
J
Jonas Hietala 已提交
613 614 615
    /// This is unsafe because it does not check
    /// to ensure that the resulting string will be valid UTF-8.
    ///
616
    /// # Examples
J
Jonas Hietala 已提交
617 618 619 620 621 622 623 624 625 626
    ///
    /// ```
    /// let mut s = String::from_str("hello");
    /// unsafe {
    ///     let vec = s.as_mut_vec();
    ///     assert!(vec == &mut vec![104, 101, 108, 108, 111]);
    ///     vec.reverse();
    /// }
    /// assert_eq!(s.as_slice(), "olleh");
    /// ```
627
    #[inline]
B
Brian Anderson 已提交
628
    #[stable(feature = "rust1", since = "1.0.0")]
629
    pub unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8> {
630 631
        &mut self.vec
    }
632

633 634
    /// Return the number of bytes in this string.
    ///
635
    /// # Examples
636 637 638 639 640
    ///
    /// ```
    /// let a = "foo".to_string();
    /// assert_eq!(a.len(), 3);
    /// ```
641
    #[inline]
B
Brian Anderson 已提交
642
    #[stable(feature = "rust1", since = "1.0.0")]
A
Alexis 已提交
643
    pub fn len(&self) -> usize { self.vec.len() }
644

645 646
    /// Returns true if the string contains no bytes
    ///
647
    /// # Examples
648 649 650 651 652 653 654
    ///
    /// ```
    /// let mut v = String::new();
    /// assert!(v.is_empty());
    /// v.push('a');
    /// assert!(!v.is_empty());
    /// ```
655
    #[inline]
B
Brian Anderson 已提交
656
    #[stable(feature = "rust1", since = "1.0.0")]
657 658 659 660
    pub fn is_empty(&self) -> bool { self.len() == 0 }

    /// Truncates the string, returning it to 0 length.
    ///
661
    /// # Examples
662 663 664 665 666 667
    ///
    /// ```
    /// let mut s = "foo".to_string();
    /// s.clear();
    /// assert!(s.is_empty());
    /// ```
668
    #[inline]
B
Brian Anderson 已提交
669
    #[stable(feature = "rust1", since = "1.0.0")]
670
    pub fn clear(&mut self) {
671 672 673 674
        self.vec.clear()
    }
}

675 676 677
impl FromUtf8Error {
    /// Consume this error, returning the bytes that were attempted to make a
    /// `String` with.
B
Brian Anderson 已提交
678
    #[stable(feature = "rust1", since = "1.0.0")]
679 680 681
    pub fn into_bytes(self) -> Vec<u8> { self.bytes }

    /// Access the underlying UTF8-error that was the cause of this error.
B
Brian Anderson 已提交
682
    #[stable(feature = "rust1", since = "1.0.0")]
683 684 685
    pub fn utf8_error(&self) -> Utf8Error { self.error }
}

686
#[stable(feature = "rust1", since = "1.0.0")]
687
impl fmt::Display for FromUtf8Error {
688
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
689
        fmt::Display::fmt(&self.error, f)
690 691 692
    }
}

B
Brian Anderson 已提交
693
#[stable(feature = "rust1", since = "1.0.0")]
694 695
impl Error for FromUtf8Error {
    fn description(&self) -> &str { "invalid utf-8" }
696 697
}

698
#[stable(feature = "rust1", since = "1.0.0")]
699
impl fmt::Display for FromUtf16Error {
700
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
701
        fmt::Display::fmt("invalid utf-16: lone surrogate found", f)
702 703 704
    }
}

B
Brian Anderson 已提交
705
#[stable(feature = "rust1", since = "1.0.0")]
706 707
impl Error for FromUtf16Error {
    fn description(&self) -> &str { "invalid utf-16" }
708 709
}

B
Brian Anderson 已提交
710
#[stable(feature = "rust1", since = "1.0.0")]
711
impl FromIterator<char> for String {
A
Alexis 已提交
712
    fn from_iter<I: IntoIterator<Item=char>>(iter: I) -> String {
713
        let mut buf = String::new();
A
Alexis 已提交
714
        buf.extend(iter);
715 716 717 718
        buf
    }
}

B
Brian Anderson 已提交
719
#[stable(feature = "rust1", since = "1.0.0")]
720
impl<'a> FromIterator<&'a str> for String {
A
Alexis 已提交
721
    fn from_iter<I: IntoIterator<Item=&'a str>>(iter: I) -> String {
722
        let mut buf = String::new();
A
Alexis 已提交
723
        buf.extend(iter);
724 725 726 727
        buf
    }
}

728
#[unstable(feature = "collections",
729
           reason = "waiting on Extend stabilization")]
G
gamazeps 已提交
730
impl Extend<char> for String {
A
Alexis 已提交
731 732
    fn extend<I: IntoIterator<Item=char>>(&mut self, iterable: I) {
        let iterator = iterable.into_iter();
733 734
        let (lower_bound, _) = iterator.size_hint();
        self.reserve(lower_bound);
735
        for ch in iterator {
736
            self.push(ch)
737 738 739 740
        }
    }
}

741
#[unstable(feature = "collections",
742
           reason = "waiting on Extend stabilization")]
743
impl<'a> Extend<&'a str> for String {
A
Alexis 已提交
744 745
    fn extend<I: IntoIterator<Item=&'a str>>(&mut self, iterable: I) {
        let iterator = iterable.into_iter();
746 747 748 749 750 751 752 753 754
        // A guess that at least one byte per iterator element will be needed.
        let (lower_bound, _) = iterator.size_hint();
        self.reserve(lower_bound);
        for s in iterator {
            self.push_str(s)
        }
    }
}

B
Brian Anderson 已提交
755
#[stable(feature = "rust1", since = "1.0.0")]
J
Jorge Aparicio 已提交
756 757 758 759 760 761 762 763 764
impl PartialEq for String {
    #[inline]
    fn eq(&self, other: &String) -> bool { PartialEq::eq(&**self, &**other) }
    #[inline]
    fn ne(&self, other: &String) -> bool { PartialEq::ne(&**self, &**other) }
}

macro_rules! impl_eq {
    ($lhs:ty, $rhs: ty) => {
B
Brian Anderson 已提交
765
        #[stable(feature = "rust1", since = "1.0.0")]
J
Jorge Aparicio 已提交
766 767 768 769 770 771 772
        impl<'a> PartialEq<$rhs> for $lhs {
            #[inline]
            fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
            #[inline]
            fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
        }

B
Brian Anderson 已提交
773
        #[stable(feature = "rust1", since = "1.0.0")]
J
Jorge Aparicio 已提交
774 775 776 777 778 779 780 781 782 783
        impl<'a> PartialEq<$lhs> for $rhs {
            #[inline]
            fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&**self, &**other) }
            #[inline]
            fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&**self, &**other) }
        }

    }
}

784
impl_eq! { String, &'a str }
A
Aaron Turon 已提交
785
impl_eq! { Cow<'a, str>, String }
J
Jorge Aparicio 已提交
786

B
Brian Anderson 已提交
787
#[stable(feature = "rust1", since = "1.0.0")]
A
Aaron Turon 已提交
788
impl<'a, 'b> PartialEq<&'b str> for Cow<'a, str> {
J
Jorge Aparicio 已提交
789 790 791 792 793 794
    #[inline]
    fn eq(&self, other: &&'b str) -> bool { PartialEq::eq(&**self, &**other) }
    #[inline]
    fn ne(&self, other: &&'b str) -> bool { PartialEq::ne(&**self, &**other) }
}

B
Brian Anderson 已提交
795
#[stable(feature = "rust1", since = "1.0.0")]
A
Aaron Turon 已提交
796
impl<'a, 'b> PartialEq<Cow<'a, str>> for &'b str {
J
Jorge Aparicio 已提交
797
    #[inline]
A
Aaron Turon 已提交
798
    fn eq(&self, other: &Cow<'a, str>) -> bool { PartialEq::eq(&**self, &**other) }
J
Jorge Aparicio 已提交
799
    #[inline]
A
Aaron Turon 已提交
800
    fn ne(&self, other: &Cow<'a, str>) -> bool { PartialEq::ne(&**self, &**other) }
J
Jorge Aparicio 已提交
801 802
}

803
#[unstable(feature = "collections", reason = "waiting on Str stabilization")]
804
impl Str for String {
805
    #[inline]
B
Brian Anderson 已提交
806
    #[stable(feature = "rust1", since = "1.0.0")]
807
    fn as_slice(&self) -> &str {
808
        unsafe { mem::transmute(&*self.vec) }
809
    }
810 811
}

B
Brian Anderson 已提交
812
#[stable(feature = "rust1", since = "1.0.0")]
813
impl Default for String {
814
    #[inline]
B
Brian Anderson 已提交
815
    #[stable(feature = "rust1", since = "1.0.0")]
816 817
    fn default() -> String {
        String::new()
818 819 820
    }
}

B
Brian Anderson 已提交
821
#[stable(feature = "rust1", since = "1.0.0")]
822
impl fmt::Display for String {
823
    #[inline]
824
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
825
        fmt::Display::fmt(&**self, f)
826 827 828
    }
}

829
#[stable(feature = "rust1", since = "1.0.0")]
830
impl fmt::Debug for String {
831
    #[inline]
832
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
833
        fmt::Debug::fmt(&**self, f)
834 835 836
    }
}

A
Alex Crichton 已提交
837 838 839 840 841 842 843
#[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)
    }
}
844

845
#[unstable(feature = "collections",
846
           reason = "recent addition, needs more experience")]
J
Jorge Aparicio 已提交
847 848 849
impl<'a> Add<&'a str> for String {
    type Output = String;

850
    #[inline]
J
Jorge Aparicio 已提交
851 852 853 854 855 856
    fn add(mut self, other: &str) -> String {
        self.push_str(other);
        self
    }
}

857
#[stable(feature = "rust1", since = "1.0.0")]
A
Alexis 已提交
858
impl ops::Index<ops::Range<usize>> for String {
N
fallout  
Nick Cameron 已提交
859
    type Output = str;
N
Nick Cameron 已提交
860
    #[inline]
A
Alexis 已提交
861
    fn index(&self, index: &ops::Range<usize>) -> &str {
862
        &self[..][*index]
N
Nick Cameron 已提交
863
    }
864
}
865
#[stable(feature = "rust1", since = "1.0.0")]
A
Alexis 已提交
866
impl ops::Index<ops::RangeTo<usize>> for String {
N
fallout  
Nick Cameron 已提交
867
    type Output = str;
N
Nick Cameron 已提交
868
    #[inline]
A
Alexis 已提交
869
    fn index(&self, index: &ops::RangeTo<usize>) -> &str {
870
        &self[..][*index]
N
Nick Cameron 已提交
871
    }
872
}
873
#[stable(feature = "rust1", since = "1.0.0")]
A
Alexis 已提交
874
impl ops::Index<ops::RangeFrom<usize>> for String {
N
fallout  
Nick Cameron 已提交
875
    type Output = str;
N
Nick Cameron 已提交
876
    #[inline]
A
Alexis 已提交
877
    fn index(&self, index: &ops::RangeFrom<usize>) -> &str {
878
        &self[..][*index]
N
Nick Cameron 已提交
879
    }
880
}
N
Nick Cameron 已提交
881 882 883 884 885
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeFull> for String {
    type Output = str;
    #[inline]
    fn index(&self, _index: &ops::RangeFull) -> &str {
886
        unsafe { mem::transmute(&*self.vec) }
N
Nick Cameron 已提交
887 888
    }
}
889

B
Brian Anderson 已提交
890
#[stable(feature = "rust1", since = "1.0.0")]
891 892 893
impl ops::Deref for String {
    type Target = str;

894
    #[inline]
895
    fn deref(&self) -> &str {
896
        unsafe { mem::transmute(&self.vec[..]) }
A
Alex Crichton 已提交
897
    }
898 899
}

900
/// Wrapper type providing a `&String` reference via `Deref`.
901
#[unstable(feature = "collections")]
902 903 904 905
pub struct DerefString<'a> {
    x: DerefVec<'a, u8>
}

906 907 908
impl<'a> Deref for DerefString<'a> {
    type Target = String;

909
    #[inline]
910 911 912 913 914 915
    fn deref<'b>(&'b self) -> &'b String {
        unsafe { mem::transmute(&*self.x) }
    }
}

/// Convert a string slice to a wrapper type providing a `&String` reference.
916 917 918 919 920 921 922 923 924 925 926 927 928
///
/// # Examples
///
/// ```
/// use std::string::as_string;
///
/// fn string_consumer(s: String) {
///     assert_eq!(s, "foo".to_string());
/// }
///
/// let string = as_string("foo").clone();
/// string_consumer(string);
/// ```
929
#[unstable(feature = "collections")]
930 931 932 933
pub fn as_string<'a>(x: &'a str) -> DerefString<'a> {
    DerefString { x: as_vec(x.as_bytes()) }
}

A
Alex Crichton 已提交
934
#[unstable(feature = "collections", reason = "associated error type may change")]
B
Brendan Zabarauskas 已提交
935
impl FromStr for String {
A
Alex Crichton 已提交
936
    type Err = ();
B
Brendan Zabarauskas 已提交
937
    #[inline]
A
Alex Crichton 已提交
938 939
    fn from_str(s: &str) -> Result<String, ()> {
        Ok(String::from_str(s))
B
Brendan Zabarauskas 已提交
940 941 942
    }
}

943
/// A generic trait for converting a value to a string
944
#[stable(feature = "rust1", since = "1.0.0")]
945 946
pub trait ToString {
    /// Converts the value of `self` to an owned string
947
    #[stable(feature = "rust1", since = "1.0.0")]
948 949 950
    fn to_string(&self) -> String;
}

951
#[stable(feature = "rust1", since = "1.0.0")]
952
impl<T: fmt::Display + ?Sized> ToString for T {
953
    #[inline]
954
    fn to_string(&self) -> String {
955
        use core::fmt::Write;
956 957 958 959 960 961 962
        let mut buf = String::new();
        let _ = buf.write_fmt(format_args!("{}", self));
        buf.shrink_to_fit();
        buf
    }
}

A
Aaron Turon 已提交
963 964
#[stable(feature = "rust1", since = "1.0.0")]
impl IntoCow<'static, str> for String {
965
    #[inline]
A
Aaron Turon 已提交
966
    fn into_cow(self) -> Cow<'static, str> {
967 968 969 970
        Cow::Owned(self)
    }
}

A
Aaron Turon 已提交
971 972
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> IntoCow<'a, str> for &'a str {
973
    #[inline]
A
Aaron Turon 已提交
974
    fn into_cow(self) -> Cow<'a, str> {
975 976 977 978
        Cow::Borrowed(self)
    }
}

A
Aaron Turon 已提交
979
impl<'a> Str for Cow<'a, str> {
A
Alex Crichton 已提交
980 981
    #[inline]
    fn as_slice<'b>(&'b self) -> &'b str {
982
        &**self
A
Alex Crichton 已提交
983 984 985
    }
}

A
Aaron Turon 已提交
986 987 988 989 990
/// A clone-on-write string
#[deprecated(since = "1.0.0", reason = "use Cow<'a, str> instead")]
#[stable(feature = "rust1", since = "1.0.0")]
pub type CowString<'a> = Cow<'a, str>;

991
#[stable(feature = "rust1", since = "1.0.0")]
992
impl fmt::Write for String {
993
    #[inline]
994 995 996 997 998 999
    fn write_str(&mut self, s: &str) -> fmt::Result {
        self.push_str(s);
        Ok(())
    }
}

1000 1001
#[cfg(test)]
mod tests {
1002
    use prelude::*;
1003 1004
    use test::Bencher;

A
Alex Crichton 已提交
1005
    use str::Utf8Error;
A
Alex Crichton 已提交
1006 1007
    use core::iter::repeat;
    use super::{as_string, CowString};
1008

1009 1010 1011
    #[test]
    fn test_as_string() {
        let x = "foo";
1012
        assert_eq!(x, &**as_string(x));
1013 1014
    }

1015 1016
    #[test]
    fn test_from_str() {
A
Alex Crichton 已提交
1017
      let owned: Option<::std::string::String> = "string".parse().ok();
1018
      assert_eq!(owned.as_ref().map(|s| &**s), Some("string"));
1019
    }
1020

1021 1022 1023 1024 1025 1026
    #[test]
    fn test_unsized_to_string() {
        let s: &str = "abc";
        let _: String = (*s).to_string();
    }

1027 1028
    #[test]
    fn test_from_utf8() {
N
NODA, Kai 已提交
1029
        let xs = b"hello".to_vec();
1030 1031
        assert_eq!(String::from_utf8(xs).unwrap(),
                   String::from_str("hello"));
1032

N
NODA, Kai 已提交
1033
        let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
1034 1035
        assert_eq!(String::from_utf8(xs).unwrap(),
                   String::from_str("ศไทย中华Việt Nam"));
1036

N
NODA, Kai 已提交
1037
        let xs = b"hello\xFF".to_vec();
1038 1039 1040
        let err = String::from_utf8(xs).err().unwrap();
        assert_eq!(err.utf8_error(), Utf8Error::TooShort);
        assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
1041 1042 1043 1044 1045
    }

    #[test]
    fn test_from_utf8_lossy() {
        let xs = b"hello";
A
Alex Crichton 已提交
1046
        let ys: CowString = "hello".into_cow();
J
Jorge Aparicio 已提交
1047
        assert_eq!(String::from_utf8_lossy(xs), ys);
1048

A
Adolfo Ochagavía 已提交
1049
        let xs = "ศไทย中华Việt Nam".as_bytes();
A
Alex Crichton 已提交
1050
        let ys: CowString = "ศไทย中华Việt Nam".into_cow();
J
Jorge Aparicio 已提交
1051
        assert_eq!(String::from_utf8_lossy(xs), ys);
1052 1053

        let xs = b"Hello\xC2 There\xFF Goodbye";
A
Adolfo Ochagavía 已提交
1054
        assert_eq!(String::from_utf8_lossy(xs),
A
Alex Crichton 已提交
1055
                   String::from_str("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow());
1056 1057 1058

        let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
        assert_eq!(String::from_utf8_lossy(xs),
A
Alex Crichton 已提交
1059
                   String::from_str("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow());
1060 1061

        let xs = b"\xF5foo\xF5\x80bar";
A
Adolfo Ochagavía 已提交
1062
        assert_eq!(String::from_utf8_lossy(xs),
A
Alex Crichton 已提交
1063
                   String::from_str("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow());
1064 1065

        let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
A
Adolfo Ochagavía 已提交
1066
        assert_eq!(String::from_utf8_lossy(xs),
A
Alex Crichton 已提交
1067
                   String::from_str("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow());
1068 1069 1070

        let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
        assert_eq!(String::from_utf8_lossy(xs),
A
Alex Crichton 已提交
1071
                   String::from_str("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow());
1072 1073

        let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
A
Alex Crichton 已提交
1074 1075
        assert_eq!(String::from_utf8_lossy(xs), String::from_str("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}\
                                               foo\u{10000}bar").into_cow());
1076 1077 1078

        // surrogates
        let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
A
Alex Crichton 已提交
1079 1080
        assert_eq!(String::from_utf8_lossy(xs), String::from_str("\u{FFFD}\u{FFFD}\u{FFFD}foo\
                                               \u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow());
1081 1082
    }

1083 1084 1085
    #[test]
    fn test_from_utf16() {
        let pairs =
A
Adolfo Ochagavía 已提交
1086
            [(String::from_str("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
1087 1088 1089 1090 1091
              vec![0xd800_u16, 0xdf45_u16, 0xd800_u16, 0xdf3f_u16,
                0xd800_u16, 0xdf3b_u16, 0xd800_u16, 0xdf46_u16,
                0xd800_u16, 0xdf39_u16, 0xd800_u16, 0xdf3b_u16,
                0xd800_u16, 0xdf30_u16, 0x000a_u16]),

A
Adolfo Ochagavía 已提交
1092
             (String::from_str("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
1093 1094 1095 1096 1097 1098 1099
              vec![0xd801_u16, 0xdc12_u16, 0xd801_u16,
                0xdc49_u16, 0xd801_u16, 0xdc2e_u16, 0xd801_u16,
                0xdc40_u16, 0xd801_u16, 0xdc32_u16, 0xd801_u16,
                0xdc4b_u16, 0x0020_u16, 0xd801_u16, 0xdc0f_u16,
                0xd801_u16, 0xdc32_u16, 0xd801_u16, 0xdc4d_u16,
                0x000a_u16]),

A
Adolfo Ochagavía 已提交
1100
             (String::from_str("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
1101 1102 1103 1104 1105 1106 1107 1108
              vec![0xd800_u16, 0xdf00_u16, 0xd800_u16, 0xdf16_u16,
                0xd800_u16, 0xdf0b_u16, 0xd800_u16, 0xdf04_u16,
                0xd800_u16, 0xdf11_u16, 0xd800_u16, 0xdf09_u16,
                0x00b7_u16, 0xd800_u16, 0xdf0c_u16, 0xd800_u16,
                0xdf04_u16, 0xd800_u16, 0xdf15_u16, 0xd800_u16,
                0xdf04_u16, 0xd800_u16, 0xdf0b_u16, 0xd800_u16,
                0xdf09_u16, 0xd800_u16, 0xdf11_u16, 0x000a_u16 ]),

A
Adolfo Ochagavía 已提交
1109
             (String::from_str("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
              vec![0xd801_u16, 0xdc8b_u16, 0xd801_u16, 0xdc98_u16,
                0xd801_u16, 0xdc88_u16, 0xd801_u16, 0xdc91_u16,
                0xd801_u16, 0xdc9b_u16, 0xd801_u16, 0xdc92_u16,
                0x0020_u16, 0xd801_u16, 0xdc95_u16, 0xd801_u16,
                0xdc93_u16, 0x0020_u16, 0xd801_u16, 0xdc88_u16,
                0xd801_u16, 0xdc9a_u16, 0xd801_u16, 0xdc8d_u16,
                0x0020_u16, 0xd801_u16, 0xdc8f_u16, 0xd801_u16,
                0xdc9c_u16, 0xd801_u16, 0xdc92_u16, 0xd801_u16,
                0xdc96_u16, 0xd801_u16, 0xdc86_u16, 0x0020_u16,
                0xd801_u16, 0xdc95_u16, 0xd801_u16, 0xdc86_u16,
                0x000a_u16 ]),
             // Issue #12318, even-numbered non-BMP planes
A
Alex Crichton 已提交
1122
             (String::from_str("\u{20000}"),
1123 1124
              vec![0xD840, 0xDC00])];

1125
        for p in &pairs {
1126
            let (s, u) = (*p).clone();
1127
            let s_as_utf16 = s.utf16_units().collect::<Vec<u16>>();
1128
            let u_as_string = String::from_utf16(&u).unwrap();
1129

1130
            assert!(::unicode::str::is_utf16(&u));
1131 1132 1133
            assert_eq!(s_as_utf16, u);

            assert_eq!(u_as_string, s);
1134
            assert_eq!(String::from_utf16_lossy(&u), s);
1135

1136
            assert_eq!(String::from_utf16(&s_as_utf16).unwrap(), s);
1137
            assert_eq!(u_as_string.utf16_units().collect::<Vec<u16>>(), u);
1138 1139 1140 1141 1142 1143 1144
        }
    }

    #[test]
    fn test_utf16_invalid() {
        // completely positive cases tested above.
        // lead + eof
1145
        assert!(String::from_utf16(&[0xD800]).is_err());
1146
        // lead + lead
1147
        assert!(String::from_utf16(&[0xD800, 0xD800]).is_err());
1148 1149

        // isolated trail
1150
        assert!(String::from_utf16(&[0x0061, 0xDC00]).is_err());
1151 1152

        // general
1153
        assert!(String::from_utf16(&[0xD800, 0xd801, 0xdc8b, 0xD800]).is_err());
1154 1155 1156 1157 1158 1159
    }

    #[test]
    fn test_from_utf16_lossy() {
        // completely positive cases tested above.
        // lead + eof
A
Alex Crichton 已提交
1160
        assert_eq!(String::from_utf16_lossy(&[0xD800]), String::from_str("\u{FFFD}"));
1161
        // lead + lead
A
Alex Crichton 已提交
1162 1163
        assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]),
                   String::from_str("\u{FFFD}\u{FFFD}"));
1164 1165

        // isolated trail
A
Alex Crichton 已提交
1166
        assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]), String::from_str("a\u{FFFD}"));
1167 1168

        // general
N
Nick Cameron 已提交
1169
        assert_eq!(String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
A
Alex Crichton 已提交
1170
                   String::from_str("\u{FFFD}𐒋\u{FFFD}"));
1171
    }
1172

1173 1174
    #[test]
    fn test_push_bytes() {
1175
        let mut s = String::from_str("ABC");
1176
        unsafe {
N
NODA, Kai 已提交
1177
            let mv = s.as_mut_vec();
N
Nick Cameron 已提交
1178
            mv.push_all(&[b'D']);
1179
        }
1180
        assert_eq!(s, "ABCD");
1181 1182 1183 1184
    }

    #[test]
    fn test_push_str() {
1185
        let mut s = String::new();
1186
        s.push_str("");
1187
        assert_eq!(&s[0..], "");
1188
        s.push_str("abc");
1189
        assert_eq!(&s[0..], "abc");
1190
        s.push_str("ประเทศไทย中华Việt Nam");
1191
        assert_eq!(&s[0..], "abcประเทศไทย中华Việt Nam");
1192 1193 1194
    }

    #[test]
1195
    fn test_push() {
1196
        let mut data = String::from_str("ประเทศไทย中");
1197 1198 1199 1200 1201
        data.push('华');
        data.push('b'); // 1 byte
        data.push('¢'); // 2 byte
        data.push('€'); // 3 byte
        data.push('𤭢'); // 4 byte
1202
        assert_eq!(data, "ประเทศไทย中华b¢€𤭢");
1203 1204
    }

1205
    #[test]
N
NODA, Kai 已提交
1206
    fn test_pop() {
1207
        let mut data = String::from_str("ประเทศไทย中华b¢€𤭢");
N
NODA, Kai 已提交
1208 1209 1210 1211 1212
        assert_eq!(data.pop().unwrap(), '𤭢'); // 4 bytes
        assert_eq!(data.pop().unwrap(), '€'); // 3 bytes
        assert_eq!(data.pop().unwrap(), '¢'); // 2 bytes
        assert_eq!(data.pop().unwrap(), 'b'); // 1 bytes
        assert_eq!(data.pop().unwrap(), '华');
1213
        assert_eq!(data, "ประเทศไทย中");
1214 1215
    }

1216 1217
    #[test]
    fn test_str_truncate() {
1218
        let mut s = String::from_str("12345");
1219
        s.truncate(5);
1220
        assert_eq!(s, "12345");
1221
        s.truncate(3);
1222
        assert_eq!(s, "123");
1223
        s.truncate(0);
1224
        assert_eq!(s, "");
1225

1226
        let mut s = String::from_str("12345");
1227
        let p = s.as_ptr();
1228 1229
        s.truncate(3);
        s.push_str("6");
1230
        let p_ = s.as_ptr();
1231 1232 1233 1234 1235 1236
        assert_eq!(p_, p);
    }

    #[test]
    #[should_fail]
    fn test_str_truncate_invalid_len() {
1237
        let mut s = String::from_str("12345");
1238 1239 1240 1241 1242 1243
        s.truncate(6);
    }

    #[test]
    #[should_fail]
    fn test_str_truncate_split_codepoint() {
A
Alex Crichton 已提交
1244
        let mut s = String::from_str("\u{FC}"); // ü
1245 1246
        s.truncate(1);
    }
1247 1248 1249

    #[test]
    fn test_str_clear() {
1250
        let mut s = String::from_str("12345");
1251 1252
        s.clear();
        assert_eq!(s.len(), 0);
1253
        assert_eq!(s, "");
1254
    }
1255 1256 1257 1258 1259

    #[test]
    fn test_str_add() {
        let a = String::from_str("12345");
        let b = a + "2";
J
Jorge Aparicio 已提交
1260
        let b = b + "2";
1261
        assert_eq!(b.len(), 7);
1262
        assert_eq!(b, "1234522");
1263
    }
1264

1265 1266 1267
    #[test]
    fn remove() {
        let mut s = "ศไทย中华Việt Nam; foobar".to_string();;
1268
        assert_eq!(s.remove(0), 'ศ');
1269
        assert_eq!(s.len(), 33);
1270
        assert_eq!(s, "ไทย中华Việt Nam; foobar");
1271
        assert_eq!(s.remove(17), 'ệ');
1272
        assert_eq!(s, "ไทย中华Vit Nam; foobar");
1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283
    }

    #[test] #[should_fail]
    fn remove_bad() {
        "ศ".to_string().remove(1);
    }

    #[test]
    fn insert() {
        let mut s = "foobar".to_string();
        s.insert(0, 'ệ');
1284
        assert_eq!(s, "ệfoobar");
1285
        s.insert(6, 'ย');
1286
        assert_eq!(s, "ệfooยbar");
1287 1288 1289 1290 1291
    }

    #[test] #[should_fail] fn insert_bad1() { "".to_string().insert(1, 't'); }
    #[test] #[should_fail] fn insert_bad2() { "ệ".to_string().insert(1, 't'); }

1292 1293 1294
    #[test]
    fn test_slicing() {
        let s = "foobar".to_string();
1295
        assert_eq!("foobar", &s[..]);
N
fallout  
Nick Cameron 已提交
1296 1297 1298
        assert_eq!("foo", &s[..3]);
        assert_eq!("bar", &s[3..]);
        assert_eq!("oob", &s[1..4]);
1299 1300
    }

1301 1302
    #[test]
    fn test_simple_types() {
T
Tobias Bucher 已提交
1303 1304
        assert_eq!(1.to_string(), "1");
        assert_eq!((-1).to_string(), "-1");
A
Alexis 已提交
1305
        assert_eq!(200.to_string(), "200");
1306 1307 1308 1309
        assert_eq!(2u8.to_string(), "2");
        assert_eq!(true.to_string(), "true");
        assert_eq!(false.to_string(), "false");
        assert_eq!(("hi".to_string()).to_string(), "hi");
1310 1311 1312 1313
    }

    #[test]
    fn test_vectors() {
A
Alexis 已提交
1314
        let x: Vec<i32> = vec![];
1315
        assert_eq!(format!("{:?}", x), "[]");
T
Tobias Bucher 已提交
1316 1317 1318
        assert_eq!(format!("{:?}", vec![1]), "[1]");
        assert_eq!(format!("{:?}", vec![1, 2, 3]), "[1, 2, 3]");
        assert!(format!("{:?}", vec![vec![], vec![1], vec![1, 1]]) ==
1319
               "[[], [1], [1, 1]]");
1320 1321
    }

1322 1323 1324 1325 1326 1327 1328
    #[test]
    fn test_from_iterator() {
        let s = "ศไทย中华Việt Nam".to_string();
        let t = "ศไทย中华";
        let u = "Việt Nam";

        let a: String = s.chars().collect();
1329
        assert_eq!(s, a);
1330 1331 1332

        let mut b = t.to_string();
        b.extend(u.chars());
1333 1334 1335 1336 1337 1338 1339 1340
        assert_eq!(s, b);

        let c: String = vec![t, u].into_iter().collect();
        assert_eq!(s, c);

        let mut d = t.to_string();
        d.extend(vec![u].into_iter());
        assert_eq!(s, d);
1341 1342
    }

1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358
    #[bench]
    fn bench_with_capacity(b: &mut Bencher) {
        b.iter(|| {
            String::with_capacity(100)
        });
    }

    #[bench]
    fn bench_push_str(b: &mut Bencher) {
        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
        b.iter(|| {
            let mut r = String::new();
            r.push_str(s);
        });
    }

1359 1360 1361 1362 1363 1364 1365
    const REPETITIONS: u64 = 10_000;

    #[bench]
    fn bench_push_str_one_byte(b: &mut Bencher) {
        b.bytes = REPETITIONS;
        b.iter(|| {
            let mut r = String::new();
1366
            for _ in 0..REPETITIONS {
1367 1368 1369 1370 1371 1372 1373 1374 1375 1376
                r.push_str("a")
            }
        });
    }

    #[bench]
    fn bench_push_char_one_byte(b: &mut Bencher) {
        b.bytes = REPETITIONS;
        b.iter(|| {
            let mut r = String::new();
1377
            for _ in 0..REPETITIONS {
1378 1379 1380 1381 1382 1383 1384 1385 1386 1387
                r.push('a')
            }
        });
    }

    #[bench]
    fn bench_push_char_two_bytes(b: &mut Bencher) {
        b.bytes = REPETITIONS * 2;
        b.iter(|| {
            let mut r = String::new();
1388
            for _ in 0..REPETITIONS {
1389 1390 1391 1392 1393
                r.push('â')
            }
        });
    }

1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406
    #[bench]
    fn from_utf8_lossy_100_ascii(b: &mut Bencher) {
        let s = b"Hello there, the quick brown fox jumped over the lazy dog! \
                  Lorem ipsum dolor sit amet, consectetur. ";

        assert_eq!(100, s.len());
        b.iter(|| {
            let _ = String::from_utf8_lossy(s);
        });
    }

    #[bench]
    fn from_utf8_lossy_100_multibyte(b: &mut Bencher) {
1407
        let s = "𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰".as_bytes();
1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423
        assert_eq!(100, s.len());
        b.iter(|| {
            let _ = String::from_utf8_lossy(s);
        });
    }

    #[bench]
    fn from_utf8_lossy_invalid(b: &mut Bencher) {
        let s = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
        b.iter(|| {
            let _ = String::from_utf8_lossy(s);
        });
    }

    #[bench]
    fn from_utf8_lossy_100_invalid(b: &mut Bencher) {
A
Alex Crichton 已提交
1424
        let s = repeat(0xf5u8).take(100).collect::<Vec<_>>();
1425
        b.iter(|| {
1426
            let _ = String::from_utf8_lossy(&s);
1427 1428
        });
    }
1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444

    #[bench]
    fn bench_exact_size_shrink_to_fit(b: &mut Bencher) {
        let s = "Hello there, the quick brown fox jumped over the lazy dog! \
                 Lorem ipsum dolor sit amet, consectetur. ";
        // ensure our operation produces an exact-size string before we benchmark it
        let mut r = String::with_capacity(s.len());
        r.push_str(s);
        assert_eq!(r.len(), r.capacity());
        b.iter(|| {
            let mut r = String::with_capacity(s.len());
            r.push_str(s);
            r.shrink_to_fit();
            r
        });
    }
1445
}