]> git.lizzy.rs Git - rust.git/blob - src/libcollections/string.rs
37a6e690f5d30ee5688931da70761286a34b67a7
[rust.git] / src / libcollections / string.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10 //
11 // ignore-lexer-test FIXME #15679
12
13 //! An owned, growable string that enforces that its contents are valid UTF-8.
14
15 #![stable]
16
17 use core::prelude::*;
18
19 use core::borrow::{Cow, IntoCow};
20 use core::default::Default;
21 use core::fmt;
22 use core::hash;
23 use core::mem;
24 use core::ptr;
25 use core::ops;
26 use core::raw::Slice as RawSlice;
27 use unicode::str as unicode_str;
28 use unicode::str::Utf16Item;
29
30 use slice::CloneSliceExt;
31 use str::{mod, CharRange, FromStr, Utf8Error};
32 use vec::{DerefVec, Vec, as_vec};
33
34 /// A growable string stored as a UTF-8 encoded buffer.
35 #[deriving(Clone, PartialOrd, Eq, Ord)]
36 #[stable]
37 pub struct String {
38     vec: Vec<u8>,
39 }
40
41 /// A possible error value from the `String::from_utf8` function.
42 #[stable]
43 pub struct FromUtf8Error {
44     bytes: Vec<u8>,
45     error: Utf8Error,
46 }
47
48 /// A possible error value from the `String::from_utf16` function.
49 #[stable]
50 #[allow(missing_copy_implementations)]
51 pub struct FromUtf16Error(());
52
53 impl String {
54     /// Creates a new string buffer initialized with the empty string.
55     ///
56     /// # Examples
57     ///
58     /// ```
59     /// let mut s = String::new();
60     /// ```
61     #[inline]
62     #[stable]
63     pub fn new() -> String {
64         String {
65             vec: Vec::new(),
66         }
67     }
68
69     /// Creates a new string buffer with the given capacity.
70     /// The string will be able to hold exactly `capacity` bytes without
71     /// reallocating. If `capacity` is 0, the string will not allocate.
72     ///
73     /// # Examples
74     ///
75     /// ```
76     /// let mut s = String::with_capacity(10);
77     /// ```
78     #[inline]
79     #[stable]
80     pub fn with_capacity(capacity: uint) -> String {
81         String {
82             vec: Vec::with_capacity(capacity),
83         }
84     }
85
86     /// Creates a new string buffer from the given string.
87     ///
88     /// # Examples
89     ///
90     /// ```
91     /// let s = String::from_str("hello");
92     /// assert_eq!(s.as_slice(), "hello");
93     /// ```
94     #[inline]
95     #[experimental = "needs investigation to see if to_string() can match perf"]
96     pub fn from_str(string: &str) -> String {
97         String { vec: string.as_bytes().to_vec() }
98     }
99
100     /// Returns the vector as a string buffer, if possible, taking care not to
101     /// copy it.
102     ///
103     /// # Failure
104     ///
105     /// If the given vector is not valid UTF-8, then the original vector and the
106     /// corresponding error is returned.
107     ///
108     /// # Examples
109     ///
110     /// ```rust
111     /// # #![allow(deprecated)]
112     /// use std::str::Utf8Error;
113     ///
114     /// let hello_vec = vec![104, 101, 108, 108, 111];
115     /// let s = String::from_utf8(hello_vec).unwrap();
116     /// assert_eq!(s, "hello");
117     ///
118     /// let invalid_vec = vec![240, 144, 128];
119     /// let s = String::from_utf8(invalid_vec).err().unwrap();
120     /// assert_eq!(s.utf8_error(), Utf8Error::TooShort);
121     /// assert_eq!(s.into_bytes(), vec![240, 144, 128]);
122     /// ```
123     #[inline]
124     #[stable]
125     pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> {
126         match str::from_utf8(vec.as_slice()) {
127             Ok(..) => Ok(String { vec: vec }),
128             Err(e) => Err(FromUtf8Error { bytes: vec, error: e })
129         }
130     }
131
132     /// Converts a vector of bytes to a new UTF-8 string.
133     /// Any invalid UTF-8 sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
134     ///
135     /// # Examples
136     ///
137     /// ```rust
138     /// let input = b"Hello \xF0\x90\x80World";
139     /// let output = String::from_utf8_lossy(input);
140     /// assert_eq!(output.as_slice(), "Hello \u{FFFD}World");
141     /// ```
142     #[stable]
143     pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> CowString<'a> {
144         match str::from_utf8(v) {
145             Ok(s) => return Cow::Borrowed(s),
146             Err(..) => {}
147         }
148
149         static TAG_CONT_U8: u8 = 128u8;
150         static REPLACEMENT: &'static [u8] = b"\xEF\xBF\xBD"; // U+FFFD in UTF-8
151         let mut i = 0;
152         let total = v.len();
153         fn unsafe_get(xs: &[u8], i: uint) -> u8 {
154             unsafe { *xs.get_unchecked(i) }
155         }
156         fn safe_get(xs: &[u8], i: uint, total: uint) -> u8 {
157             if i >= total {
158                 0
159             } else {
160                 unsafe_get(xs, i)
161             }
162         }
163
164         let mut res = String::with_capacity(total);
165
166         if i > 0 {
167             unsafe {
168                 res.as_mut_vec().push_all(v[..i])
169             };
170         }
171
172         // subseqidx is the index of the first byte of the subsequence we're looking at.
173         // It's used to copy a bunch of contiguous good codepoints at once instead of copying
174         // them one by one.
175         let mut subseqidx = 0;
176
177         while i < total {
178             let i_ = i;
179             let byte = unsafe_get(v, i);
180             i += 1;
181
182             macro_rules! error(() => ({
183                 unsafe {
184                     if subseqidx != i_ {
185                         res.as_mut_vec().push_all(v[subseqidx..i_]);
186                     }
187                     subseqidx = i;
188                     res.as_mut_vec().push_all(REPLACEMENT);
189                 }
190             }));
191
192             if byte < 128u8 {
193                 // subseqidx handles this
194             } else {
195                 let w = unicode_str::utf8_char_width(byte);
196
197                 match w {
198                     2 => {
199                         if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
200                             error!();
201                             continue;
202                         }
203                         i += 1;
204                     }
205                     3 => {
206                         match (byte, safe_get(v, i, total)) {
207                             (0xE0         , 0xA0 ... 0xBF) => (),
208                             (0xE1 ... 0xEC, 0x80 ... 0xBF) => (),
209                             (0xED         , 0x80 ... 0x9F) => (),
210                             (0xEE ... 0xEF, 0x80 ... 0xBF) => (),
211                             _ => {
212                                 error!();
213                                 continue;
214                             }
215                         }
216                         i += 1;
217                         if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
218                             error!();
219                             continue;
220                         }
221                         i += 1;
222                     }
223                     4 => {
224                         match (byte, safe_get(v, i, total)) {
225                             (0xF0         , 0x90 ... 0xBF) => (),
226                             (0xF1 ... 0xF3, 0x80 ... 0xBF) => (),
227                             (0xF4         , 0x80 ... 0x8F) => (),
228                             _ => {
229                                 error!();
230                                 continue;
231                             }
232                         }
233                         i += 1;
234                         if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
235                             error!();
236                             continue;
237                         }
238                         i += 1;
239                         if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
240                             error!();
241                             continue;
242                         }
243                         i += 1;
244                     }
245                     _ => {
246                         error!();
247                         continue;
248                     }
249                 }
250             }
251         }
252         if subseqidx < total {
253             unsafe {
254                 res.as_mut_vec().push_all(v[subseqidx..total])
255             };
256         }
257         Cow::Owned(res)
258     }
259
260     /// Decode a UTF-16 encoded vector `v` into a `String`, returning `None`
261     /// if `v` contains any invalid data.
262     ///
263     /// # Examples
264     ///
265     /// ```rust
266     /// // 𝄞music
267     /// let mut v = &mut [0xD834, 0xDD1E, 0x006d, 0x0075,
268     ///                   0x0073, 0x0069, 0x0063];
269     /// assert_eq!(String::from_utf16(v).unwrap(),
270     ///            "𝄞music".to_string());
271     ///
272     /// // 𝄞mu<invalid>ic
273     /// v[4] = 0xD800;
274     /// assert!(String::from_utf16(v).is_err());
275     /// ```
276     #[stable]
277     pub fn from_utf16(v: &[u16]) -> Result<String, FromUtf16Error> {
278         let mut s = String::with_capacity(v.len());
279         for c in unicode_str::utf16_items(v) {
280             match c {
281                 Utf16Item::ScalarValue(c) => s.push(c),
282                 Utf16Item::LoneSurrogate(_) => return Err(FromUtf16Error(())),
283             }
284         }
285         Ok(s)
286     }
287
288     /// Decode a UTF-16 encoded vector `v` into a string, replacing
289     /// invalid data with the replacement character (U+FFFD).
290     ///
291     /// # Examples
292     ///
293     /// ```rust
294     /// // 𝄞mus<invalid>ic<invalid>
295     /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
296     ///           0x0073, 0xDD1E, 0x0069, 0x0063,
297     ///           0xD834];
298     ///
299     /// assert_eq!(String::from_utf16_lossy(v),
300     ///            "𝄞mus\u{FFFD}ic\u{FFFD}".to_string());
301     /// ```
302     #[stable]
303     pub fn from_utf16_lossy(v: &[u16]) -> String {
304         unicode_str::utf16_items(v).map(|c| c.to_char_lossy()).collect()
305     }
306
307     /// Convert a vector of `char`s to a `String`.
308     ///
309     /// # Examples
310     ///
311     /// ```rust
312     /// # #![allow(deprecated)]
313     /// let chars = &['h', 'e', 'l', 'l', 'o'];
314     /// let s = String::from_chars(chars);
315     /// assert_eq!(s.as_slice(), "hello");
316     /// ```
317     #[inline]
318     #[deprecated = "use .collect() instead"]
319     pub fn from_chars(chs: &[char]) -> String {
320         chs.iter().map(|c| *c).collect()
321     }
322
323     /// Creates a new `String` from a length, capacity, and pointer.
324     ///
325     /// This is unsafe because:
326     /// * We call `Vec::from_raw_parts` to get a `Vec<u8>`;
327     /// * We assume that the `Vec` contains valid UTF-8.
328     #[inline]
329     #[stable]
330     pub unsafe fn from_raw_parts(buf: *mut u8, length: uint, capacity: uint) -> String {
331         String {
332             vec: Vec::from_raw_parts(buf, length, capacity),
333         }
334     }
335
336     /// Creates a `String` from a null-terminated `*const u8` buffer.
337     ///
338     /// This function is unsafe because we dereference memory until we find the
339     /// NUL character, which is not guaranteed to be present. Additionally, the
340     /// slice is not checked to see whether it contains valid UTF-8
341     #[unstable = "just renamed from `mod raw`"]
342     pub unsafe fn from_raw_buf(buf: *const u8) -> String {
343         String::from_str(str::from_c_str(buf as *const i8))
344     }
345
346     /// Creates a `String` from a `*const u8` buffer of the given length.
347     ///
348     /// This function is unsafe because it blindly assumes the validity of the
349     /// pointer `buf` for `len` bytes of memory. This function will copy the
350     /// memory from `buf` into a new allocation (owned by the returned
351     /// `String`).
352     ///
353     /// This function is also unsafe because it does not validate that the
354     /// buffer is valid UTF-8 encoded data.
355     #[unstable = "just renamed from `mod raw`"]
356     pub unsafe fn from_raw_buf_len(buf: *const u8, len: uint) -> String {
357         String::from_utf8_unchecked(Vec::from_raw_buf(buf, len))
358     }
359
360     /// Converts a vector of bytes to a new `String` without checking if
361     /// it contains valid UTF-8. This is unsafe because it assumes that
362     /// the UTF-8-ness of the vector has already been validated.
363     #[inline]
364     #[stable]
365     pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String {
366         String { vec: bytes }
367     }
368
369     /// Return the underlying byte buffer, encoded as UTF-8.
370     ///
371     /// # Examples
372     ///
373     /// ```
374     /// let s = String::from_str("hello");
375     /// let bytes = s.into_bytes();
376     /// assert_eq!(bytes, vec![104, 101, 108, 108, 111]);
377     /// ```
378     #[inline]
379     #[stable]
380     pub fn into_bytes(self) -> Vec<u8> {
381         self.vec
382     }
383
384     /// Creates a string buffer by repeating a character `length` times.
385     ///
386     /// # Examples
387     ///
388     /// ```
389     /// # #![allow(deprecated)]
390     /// let s = String::from_char(5, 'a');
391     /// assert_eq!(s.as_slice(), "aaaaa");
392     /// ```
393     #[inline]
394     #[deprecated = "use repeat(ch).take(length).collect() instead"]
395     pub fn from_char(length: uint, ch: char) -> String {
396         if length == 0 {
397             return String::new()
398         }
399
400         let mut buf = String::new();
401         buf.push(ch);
402         let size = buf.len() * (length - 1);
403         buf.reserve_exact(size);
404         for _ in range(1, length) {
405             buf.push(ch)
406         }
407         buf
408     }
409
410     /// Pushes the given string onto this string buffer.
411     ///
412     /// # Examples
413     ///
414     /// ```
415     /// let mut s = String::from_str("foo");
416     /// s.push_str("bar");
417     /// assert_eq!(s.as_slice(), "foobar");
418     /// ```
419     #[inline]
420     #[stable]
421     pub fn push_str(&mut self, string: &str) {
422         self.vec.push_all(string.as_bytes())
423     }
424
425     /// Pushes `ch` onto the given string `count` times.
426     ///
427     /// # Examples
428     ///
429     /// ```
430     /// # #![allow(deprecated)]
431     /// let mut s = String::from_str("foo");
432     /// s.grow(5, 'Z');
433     /// assert_eq!(s.as_slice(), "fooZZZZZ");
434     /// ```
435     #[inline]
436     #[deprecated = "deprecated in favor of .extend(repeat(ch).take(count))"]
437     pub fn grow(&mut self, count: uint, ch: char) {
438         for _ in range(0, count) {
439             self.push(ch)
440         }
441     }
442
443     /// Returns the number of bytes that this string buffer can hold without
444     /// reallocating.
445     ///
446     /// # Examples
447     ///
448     /// ```
449     /// let s = String::with_capacity(10);
450     /// assert!(s.capacity() >= 10);
451     /// ```
452     #[inline]
453     #[stable]
454     pub fn capacity(&self) -> uint {
455         self.vec.capacity()
456     }
457
458     /// Deprecated: Renamed to `reserve`.
459     #[deprecated = "Renamed to `reserve`"]
460     pub fn reserve_additional(&mut self, extra: uint) {
461         self.vec.reserve(extra)
462     }
463
464     /// Reserves capacity for at least `additional` more bytes to be inserted
465     /// in the given `String`. The collection may reserve more space to avoid
466     /// frequent reallocations.
467     ///
468     /// # Panics
469     ///
470     /// Panics if the new capacity overflows `uint`.
471     ///
472     /// # Examples
473     ///
474     /// ```
475     /// let mut s = String::new();
476     /// s.reserve(10);
477     /// assert!(s.capacity() >= 10);
478     /// ```
479     #[inline]
480     #[stable]
481     pub fn reserve(&mut self, additional: uint) {
482         self.vec.reserve(additional)
483     }
484
485     /// Reserves the minimum capacity for exactly `additional` more bytes to be
486     /// inserted in the given `String`. Does nothing if the capacity is already
487     /// sufficient.
488     ///
489     /// Note that the allocator may give the collection more space than it
490     /// requests. Therefore capacity can not be relied upon to be precisely
491     /// minimal. Prefer `reserve` if future insertions are expected.
492     ///
493     /// # Panics
494     ///
495     /// Panics if the new capacity overflows `uint`.
496     ///
497     /// # Examples
498     ///
499     /// ```
500     /// let mut s = String::new();
501     /// s.reserve(10);
502     /// assert!(s.capacity() >= 10);
503     /// ```
504     #[inline]
505     #[stable]
506     pub fn reserve_exact(&mut self, additional: uint) {
507         self.vec.reserve_exact(additional)
508     }
509
510     /// Shrinks the capacity of this string buffer to match its length.
511     ///
512     /// # Examples
513     ///
514     /// ```
515     /// let mut s = String::from_str("foo");
516     /// s.reserve(100);
517     /// assert!(s.capacity() >= 100);
518     /// s.shrink_to_fit();
519     /// assert_eq!(s.capacity(), 3);
520     /// ```
521     #[inline]
522     #[stable]
523     pub fn shrink_to_fit(&mut self) {
524         self.vec.shrink_to_fit()
525     }
526
527     /// Adds the given character to the end of the string.
528     ///
529     /// # Examples
530     ///
531     /// ```
532     /// let mut s = String::from_str("abc");
533     /// s.push('1');
534     /// s.push('2');
535     /// s.push('3');
536     /// assert_eq!(s.as_slice(), "abc123");
537     /// ```
538     #[inline]
539     #[stable]
540     pub fn push(&mut self, ch: char) {
541         if (ch as u32) < 0x80 {
542             self.vec.push(ch as u8);
543             return;
544         }
545
546         let cur_len = self.len();
547         // This may use up to 4 bytes.
548         self.vec.reserve(4);
549
550         unsafe {
551             // Attempt to not use an intermediate buffer by just pushing bytes
552             // directly onto this string.
553             let slice = RawSlice {
554                 data: self.vec.as_ptr().offset(cur_len as int),
555                 len: 4,
556             };
557             let used = ch.encode_utf8(mem::transmute(slice)).unwrap_or(0);
558             self.vec.set_len(cur_len + used);
559         }
560     }
561
562     /// Works with the underlying buffer as a byte slice.
563     ///
564     /// # Examples
565     ///
566     /// ```
567     /// let s = String::from_str("hello");
568     /// let b: &[_] = &[104, 101, 108, 108, 111];
569     /// assert_eq!(s.as_bytes(), b);
570     /// ```
571     #[inline]
572     #[stable]
573     pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
574         self.vec.as_slice()
575     }
576
577     /// Shortens a string to the specified length.
578     ///
579     /// # Panics
580     ///
581     /// Panics if `new_len` > current length,
582     /// or if `new_len` is not a character boundary.
583     ///
584     /// # Examples
585     ///
586     /// ```
587     /// let mut s = String::from_str("hello");
588     /// s.truncate(2);
589     /// assert_eq!(s.as_slice(), "he");
590     /// ```
591     #[inline]
592     #[stable]
593     pub fn truncate(&mut self, new_len: uint) {
594         assert!(self.is_char_boundary(new_len));
595         self.vec.truncate(new_len)
596     }
597
598     /// Removes the last character from the string buffer and returns it.
599     /// Returns `None` if this string buffer is empty.
600     ///
601     /// # Examples
602     ///
603     /// ```
604     /// let mut s = String::from_str("foo");
605     /// assert_eq!(s.pop(), Some('o'));
606     /// assert_eq!(s.pop(), Some('o'));
607     /// assert_eq!(s.pop(), Some('f'));
608     /// assert_eq!(s.pop(), None);
609     /// ```
610     #[inline]
611     #[stable]
612     pub fn pop(&mut self) -> Option<char> {
613         let len = self.len();
614         if len == 0 {
615             return None
616         }
617
618         let CharRange {ch, next} = self.char_range_at_reverse(len);
619         unsafe {
620             self.vec.set_len(next);
621         }
622         Some(ch)
623     }
624
625     /// Removes the character from the string buffer at byte position `idx` and
626     /// returns it.
627     ///
628     /// # Warning
629     ///
630     /// This is an O(n) operation as it requires copying every element in the
631     /// buffer.
632     ///
633     /// # Panics
634     ///
635     /// If `idx` does not lie on a character boundary, or if it is out of
636     /// bounds, then this function will panic.
637     ///
638     /// # Examples
639     ///
640     /// ```
641     /// let mut s = String::from_str("foo");
642     /// assert_eq!(s.remove(0), 'f');
643     /// assert_eq!(s.remove(1), 'o');
644     /// assert_eq!(s.remove(0), 'o');
645     /// ```
646     #[stable]
647     pub fn remove(&mut self, idx: uint) -> char {
648         let len = self.len();
649         assert!(idx <= len);
650
651         let CharRange { ch, next } = self.char_range_at(idx);
652         unsafe {
653             ptr::copy_memory(self.vec.as_mut_ptr().offset(idx as int),
654                              self.vec.as_ptr().offset(next as int),
655                              len - next);
656             self.vec.set_len(len - (next - idx));
657         }
658         ch
659     }
660
661     /// Insert a character into the string buffer at byte position `idx`.
662     ///
663     /// # Warning
664     ///
665     /// This is an O(n) operation as it requires copying every element in the
666     /// buffer.
667     ///
668     /// # Panics
669     ///
670     /// If `idx` does not lie on a character boundary or is out of bounds, then
671     /// this function will panic.
672     #[stable]
673     pub fn insert(&mut self, idx: uint, ch: char) {
674         let len = self.len();
675         assert!(idx <= len);
676         assert!(self.is_char_boundary(idx));
677         self.vec.reserve(4);
678         let mut bits = [0; 4];
679         let amt = ch.encode_utf8(&mut bits).unwrap();
680
681         unsafe {
682             ptr::copy_memory(self.vec.as_mut_ptr().offset((idx + amt) as int),
683                              self.vec.as_ptr().offset(idx as int),
684                              len - idx);
685             ptr::copy_memory(self.vec.as_mut_ptr().offset(idx as int),
686                              bits.as_ptr(),
687                              amt);
688             self.vec.set_len(len + amt);
689         }
690     }
691
692     /// Views the string buffer as a mutable sequence of bytes.
693     ///
694     /// This is unsafe because it does not check
695     /// to ensure that the resulting string will be valid UTF-8.
696     ///
697     /// # Examples
698     ///
699     /// ```
700     /// let mut s = String::from_str("hello");
701     /// unsafe {
702     ///     let vec = s.as_mut_vec();
703     ///     assert!(vec == &mut vec![104, 101, 108, 108, 111]);
704     ///     vec.reverse();
705     /// }
706     /// assert_eq!(s.as_slice(), "olleh");
707     /// ```
708     #[stable]
709     pub unsafe fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec<u8> {
710         &mut self.vec
711     }
712
713     /// Return the number of bytes in this string.
714     ///
715     /// # Examples
716     ///
717     /// ```
718     /// let a = "foo".to_string();
719     /// assert_eq!(a.len(), 3);
720     /// ```
721     #[inline]
722     #[stable]
723     pub fn len(&self) -> uint { self.vec.len() }
724
725     /// Returns true if the string contains no bytes
726     ///
727     /// # Examples
728     ///
729     /// ```
730     /// let mut v = String::new();
731     /// assert!(v.is_empty());
732     /// v.push('a');
733     /// assert!(!v.is_empty());
734     /// ```
735     #[stable]
736     pub fn is_empty(&self) -> bool { self.len() == 0 }
737
738     /// Truncates the string, returning it to 0 length.
739     ///
740     /// # Examples
741     ///
742     /// ```
743     /// let mut s = "foo".to_string();
744     /// s.clear();
745     /// assert!(s.is_empty());
746     /// ```
747     #[inline]
748     #[stable]
749     pub fn clear(&mut self) {
750         self.vec.clear()
751     }
752 }
753
754 impl FromUtf8Error {
755     /// Consume this error, returning the bytes that were attempted to make a
756     /// `String` with.
757     #[stable]
758     pub fn into_bytes(self) -> Vec<u8> { self.bytes }
759
760     /// Access the underlying UTF8-error that was the cause of this error.
761     #[stable]
762     pub fn utf8_error(&self) -> Utf8Error { self.error }
763 }
764
765 impl fmt::Show for FromUtf8Error {
766     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
767         self.error.fmt(f)
768     }
769 }
770
771 impl fmt::Show for FromUtf16Error {
772     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
773         "invalid utf-16: lone surrogate found".fmt(f)
774     }
775 }
776
777 #[experimental = "waiting on FromIterator stabilization"]
778 impl FromIterator<char> for String {
779     fn from_iter<I:Iterator<char>>(iterator: I) -> String {
780         let mut buf = String::new();
781         buf.extend(iterator);
782         buf
783     }
784 }
785
786 #[experimental = "waiting on FromIterator stabilization"]
787 impl<'a> FromIterator<&'a str> for String {
788     fn from_iter<I:Iterator<&'a str>>(iterator: I) -> String {
789         let mut buf = String::new();
790         buf.extend(iterator);
791         buf
792     }
793 }
794
795 #[experimental = "waiting on Extend stabilization"]
796 impl Extend<char> for String {
797     fn extend<I:Iterator<char>>(&mut self, mut iterator: I) {
798         let (lower_bound, _) = iterator.size_hint();
799         self.reserve(lower_bound);
800         for ch in iterator {
801             self.push(ch)
802         }
803     }
804 }
805
806 #[experimental = "waiting on Extend stabilization"]
807 impl<'a> Extend<&'a str> for String {
808     fn extend<I: Iterator<&'a str>>(&mut self, mut iterator: I) {
809         // A guess that at least one byte per iterator element will be needed.
810         let (lower_bound, _) = iterator.size_hint();
811         self.reserve(lower_bound);
812         for s in iterator {
813             self.push_str(s)
814         }
815     }
816 }
817
818 #[stable]
819 impl PartialEq for String {
820     #[inline]
821     fn eq(&self, other: &String) -> bool { PartialEq::eq(&**self, &**other) }
822     #[inline]
823     fn ne(&self, other: &String) -> bool { PartialEq::ne(&**self, &**other) }
824 }
825
826 macro_rules! impl_eq {
827     ($lhs:ty, $rhs: ty) => {
828         #[stable]
829         impl<'a> PartialEq<$rhs> for $lhs {
830             #[inline]
831             fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
832             #[inline]
833             fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
834         }
835
836         #[stable]
837         impl<'a> PartialEq<$lhs> for $rhs {
838             #[inline]
839             fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&**self, &**other) }
840             #[inline]
841             fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&**self, &**other) }
842         }
843
844     }
845 }
846
847 impl_eq! { String, &'a str }
848 impl_eq! { CowString<'a>, String }
849
850 #[stable]
851 impl<'a, 'b> PartialEq<&'b str> for CowString<'a> {
852     #[inline]
853     fn eq(&self, other: &&'b str) -> bool { PartialEq::eq(&**self, &**other) }
854     #[inline]
855     fn ne(&self, other: &&'b str) -> bool { PartialEq::ne(&**self, &**other) }
856 }
857
858 #[stable]
859 impl<'a, 'b> PartialEq<CowString<'a>> for &'b str {
860     #[inline]
861     fn eq(&self, other: &CowString<'a>) -> bool { PartialEq::eq(&**self, &**other) }
862     #[inline]
863     fn ne(&self, other: &CowString<'a>) -> bool { PartialEq::ne(&**self, &**other) }
864 }
865
866 #[experimental = "waiting on Str stabilization"]
867 #[allow(deprecated)]
868 impl Str for String {
869     #[inline]
870     #[stable]
871     fn as_slice<'a>(&'a self) -> &'a str {
872         unsafe { mem::transmute(self.vec.as_slice()) }
873     }
874 }
875
876 #[stable]
877 impl Default for String {
878     #[stable]
879     fn default() -> String {
880         String::new()
881     }
882 }
883
884 #[experimental = "waiting on Show stabilization"]
885 impl fmt::Show for String {
886     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
887         (**self).fmt(f)
888     }
889 }
890
891 #[experimental = "waiting on Hash stabilization"]
892 impl<H: hash::Writer> hash::Hash<H> for String {
893     #[inline]
894     fn hash(&self, hasher: &mut H) {
895         (**self).hash(hasher)
896     }
897 }
898
899 #[allow(deprecated)]
900 #[deprecated = "Use overloaded `core::cmp::PartialEq`"]
901 impl<'a, S: Str> Equiv<S> for String {
902     #[inline]
903     fn equiv(&self, other: &S) -> bool {
904         self.as_slice() == other.as_slice()
905     }
906 }
907
908 #[experimental = "waiting on Add stabilization"]
909 impl<'a> Add<&'a str, String> for String {
910     fn add(mut self, other: &str) -> String {
911         self.push_str(other);
912         self
913     }
914 }
915
916 impl ops::Slice<uint, str> for String {
917     #[inline]
918     fn as_slice_<'a>(&'a self) -> &'a str {
919         unsafe { mem::transmute(self.vec.as_slice()) }
920     }
921
922     #[inline]
923     fn slice_from_or_fail<'a>(&'a self, from: &uint) -> &'a str {
924         self[][*from..]
925     }
926
927     #[inline]
928     fn slice_to_or_fail<'a>(&'a self, to: &uint) -> &'a str {
929         self[][..*to]
930     }
931
932     #[inline]
933     fn slice_or_fail<'a>(&'a self, from: &uint, to: &uint) -> &'a str {
934         self[][*from..*to]
935     }
936 }
937
938 #[experimental = "waiting on Deref stabilization"]
939 impl ops::Deref<str> for String {
940     fn deref<'a>(&'a self) -> &'a str {
941         unsafe { mem::transmute(self.vec[]) }
942     }
943 }
944
945 /// Wrapper type providing a `&String` reference via `Deref`.
946 #[experimental]
947 pub struct DerefString<'a> {
948     x: DerefVec<'a, u8>
949 }
950
951 impl<'a> Deref<String> for DerefString<'a> {
952     fn deref<'b>(&'b self) -> &'b String {
953         unsafe { mem::transmute(&*self.x) }
954     }
955 }
956
957 /// Convert a string slice to a wrapper type providing a `&String` reference.
958 ///
959 /// # Examples
960 ///
961 /// ```
962 /// use std::string::as_string;
963 ///
964 /// fn string_consumer(s: String) {
965 ///     assert_eq!(s, "foo".to_string());
966 /// }
967 ///
968 /// let string = as_string("foo").clone();
969 /// string_consumer(string);
970 /// ```
971 #[experimental]
972 pub fn as_string<'a>(x: &'a str) -> DerefString<'a> {
973     DerefString { x: as_vec(x.as_bytes()) }
974 }
975
976 impl FromStr for String {
977     #[inline]
978     fn from_str(s: &str) -> Option<String> {
979         Some(String::from_str(s))
980     }
981 }
982
983 /// Trait for converting a type to a string, consuming it in the process.
984 #[deprecated = "trait will be removed"]
985 pub trait IntoString {
986     /// Consume and convert to a string.
987     fn into_string(self) -> String;
988 }
989
990 /// A generic trait for converting a value to a string
991 pub trait ToString {
992     /// Converts the value of `self` to an owned string
993     fn to_string(&self) -> String;
994 }
995
996 impl<T: fmt::Show> ToString for T {
997     fn to_string(&self) -> String {
998         let mut buf = Vec::<u8>::new();
999         let _ = fmt::write(&mut buf, format_args!("{}", *self));
1000         String::from_utf8(buf).unwrap()
1001     }
1002 }
1003
1004 impl IntoCow<'static, String, str> for String {
1005     fn into_cow(self) -> CowString<'static> {
1006         Cow::Owned(self)
1007     }
1008 }
1009
1010 impl<'a> IntoCow<'a, String, str> for &'a str {
1011     fn into_cow(self) -> CowString<'a> {
1012         Cow::Borrowed(self)
1013     }
1014 }
1015
1016 /// Unsafe operations
1017 #[deprecated]
1018 pub mod raw {
1019     use super::String;
1020     use vec::Vec;
1021
1022     /// Creates a new `String` from a length, capacity, and pointer.
1023     ///
1024     /// This is unsafe because:
1025     /// * We call `Vec::from_raw_parts` to get a `Vec<u8>`;
1026     /// * We assume that the `Vec` contains valid UTF-8.
1027     #[inline]
1028     #[deprecated = "renamed to String::from_raw_parts"]
1029     pub unsafe fn from_parts(buf: *mut u8, length: uint, capacity: uint) -> String {
1030         String::from_raw_parts(buf, length, capacity)
1031     }
1032
1033     /// Creates a `String` from a `*const u8` buffer of the given length.
1034     ///
1035     /// This function is unsafe because of two reasons:
1036     ///
1037     /// * A raw pointer is dereferenced and transmuted to `&[u8]`;
1038     /// * The slice is not checked to see whether it contains valid UTF-8.
1039     #[deprecated = "renamed to String::from_raw_buf_len"]
1040     pub unsafe fn from_buf_len(buf: *const u8, len: uint) -> String {
1041         String::from_raw_buf_len(buf, len)
1042     }
1043
1044     /// Creates a `String` from a null-terminated `*const u8` buffer.
1045     ///
1046     /// This function is unsafe because we dereference memory until we find the NUL character,
1047     /// which is not guaranteed to be present. Additionally, the slice is not checked to see
1048     /// whether it contains valid UTF-8
1049     #[deprecated = "renamed to String::from_raw_buf"]
1050     pub unsafe fn from_buf(buf: *const u8) -> String {
1051         String::from_raw_buf(buf)
1052     }
1053
1054     /// Converts a vector of bytes to a new `String` without checking if
1055     /// it contains valid UTF-8. This is unsafe because it assumes that
1056     /// the UTF-8-ness of the vector has already been validated.
1057     #[inline]
1058     #[deprecated = "renamed to String::from_utf8_unchecked"]
1059     pub unsafe fn from_utf8(bytes: Vec<u8>) -> String {
1060         String::from_utf8_unchecked(bytes)
1061     }
1062 }
1063
1064 /// A clone-on-write string
1065 #[stable]
1066 pub type CowString<'a> = Cow<'a, String, str>;
1067
1068 #[allow(deprecated)]
1069 impl<'a> Str for CowString<'a> {
1070     #[inline]
1071     fn as_slice<'b>(&'b self) -> &'b str {
1072         (**self).as_slice()
1073     }
1074 }
1075
1076 #[cfg(test)]
1077 mod tests {
1078     use prelude::*;
1079     use test::Bencher;
1080
1081     use str::Utf8Error;
1082     use str;
1083     use super::as_string;
1084
1085     #[test]
1086     fn test_as_string() {
1087         let x = "foo";
1088         assert_eq!(x, as_string(x).as_slice());
1089     }
1090
1091     #[test]
1092     fn test_from_str() {
1093       let owned: Option<::std::string::String> = from_str("string");
1094       assert_eq!(owned.as_ref().map(|s| s.as_slice()), Some("string"));
1095     }
1096
1097     #[test]
1098     fn test_from_utf8() {
1099         let xs = b"hello".to_vec();
1100         assert_eq!(String::from_utf8(xs).unwrap(),
1101                    String::from_str("hello"));
1102
1103         let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
1104         assert_eq!(String::from_utf8(xs).unwrap(),
1105                    String::from_str("ศไทย中华Việt Nam"));
1106
1107         let xs = b"hello\xFF".to_vec();
1108         let err = String::from_utf8(xs).err().unwrap();
1109         assert_eq!(err.utf8_error(), Utf8Error::TooShort);
1110         assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
1111     }
1112
1113     #[test]
1114     fn test_from_utf8_lossy() {
1115         let xs = b"hello";
1116         let ys: str::CowString = "hello".into_cow();
1117         assert_eq!(String::from_utf8_lossy(xs), ys);
1118
1119         let xs = "ศไทย中华Việt Nam".as_bytes();
1120         let ys: str::CowString = "ศไทย中华Việt Nam".into_cow();
1121         assert_eq!(String::from_utf8_lossy(xs), ys);
1122
1123         let xs = b"Hello\xC2 There\xFF Goodbye";
1124         assert_eq!(String::from_utf8_lossy(xs),
1125                    String::from_str("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow());
1126
1127         let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
1128         assert_eq!(String::from_utf8_lossy(xs),
1129                    String::from_str("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow());
1130
1131         let xs = b"\xF5foo\xF5\x80bar";
1132         assert_eq!(String::from_utf8_lossy(xs),
1133                    String::from_str("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow());
1134
1135         let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
1136         assert_eq!(String::from_utf8_lossy(xs),
1137                    String::from_str("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow());
1138
1139         let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
1140         assert_eq!(String::from_utf8_lossy(xs),
1141                    String::from_str("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow());
1142
1143         let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
1144         assert_eq!(String::from_utf8_lossy(xs), String::from_str("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}\
1145                                                foo\u{10000}bar").into_cow());
1146
1147         // surrogates
1148         let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
1149         assert_eq!(String::from_utf8_lossy(xs), String::from_str("\u{FFFD}\u{FFFD}\u{FFFD}foo\
1150                                                \u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow());
1151     }
1152
1153     #[test]
1154     fn test_from_utf16() {
1155         let pairs =
1156             [(String::from_str("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
1157               vec![0xd800_u16, 0xdf45_u16, 0xd800_u16, 0xdf3f_u16,
1158                 0xd800_u16, 0xdf3b_u16, 0xd800_u16, 0xdf46_u16,
1159                 0xd800_u16, 0xdf39_u16, 0xd800_u16, 0xdf3b_u16,
1160                 0xd800_u16, 0xdf30_u16, 0x000a_u16]),
1161
1162              (String::from_str("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
1163               vec![0xd801_u16, 0xdc12_u16, 0xd801_u16,
1164                 0xdc49_u16, 0xd801_u16, 0xdc2e_u16, 0xd801_u16,
1165                 0xdc40_u16, 0xd801_u16, 0xdc32_u16, 0xd801_u16,
1166                 0xdc4b_u16, 0x0020_u16, 0xd801_u16, 0xdc0f_u16,
1167                 0xd801_u16, 0xdc32_u16, 0xd801_u16, 0xdc4d_u16,
1168                 0x000a_u16]),
1169
1170              (String::from_str("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
1171               vec![0xd800_u16, 0xdf00_u16, 0xd800_u16, 0xdf16_u16,
1172                 0xd800_u16, 0xdf0b_u16, 0xd800_u16, 0xdf04_u16,
1173                 0xd800_u16, 0xdf11_u16, 0xd800_u16, 0xdf09_u16,
1174                 0x00b7_u16, 0xd800_u16, 0xdf0c_u16, 0xd800_u16,
1175                 0xdf04_u16, 0xd800_u16, 0xdf15_u16, 0xd800_u16,
1176                 0xdf04_u16, 0xd800_u16, 0xdf0b_u16, 0xd800_u16,
1177                 0xdf09_u16, 0xd800_u16, 0xdf11_u16, 0x000a_u16 ]),
1178
1179              (String::from_str("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
1180               vec![0xd801_u16, 0xdc8b_u16, 0xd801_u16, 0xdc98_u16,
1181                 0xd801_u16, 0xdc88_u16, 0xd801_u16, 0xdc91_u16,
1182                 0xd801_u16, 0xdc9b_u16, 0xd801_u16, 0xdc92_u16,
1183                 0x0020_u16, 0xd801_u16, 0xdc95_u16, 0xd801_u16,
1184                 0xdc93_u16, 0x0020_u16, 0xd801_u16, 0xdc88_u16,
1185                 0xd801_u16, 0xdc9a_u16, 0xd801_u16, 0xdc8d_u16,
1186                 0x0020_u16, 0xd801_u16, 0xdc8f_u16, 0xd801_u16,
1187                 0xdc9c_u16, 0xd801_u16, 0xdc92_u16, 0xd801_u16,
1188                 0xdc96_u16, 0xd801_u16, 0xdc86_u16, 0x0020_u16,
1189                 0xd801_u16, 0xdc95_u16, 0xd801_u16, 0xdc86_u16,
1190                 0x000a_u16 ]),
1191              // Issue #12318, even-numbered non-BMP planes
1192              (String::from_str("\u{20000}"),
1193               vec![0xD840, 0xDC00])];
1194
1195         for p in pairs.iter() {
1196             let (s, u) = (*p).clone();
1197             let s_as_utf16 = s.utf16_units().collect::<Vec<u16>>();
1198             let u_as_string = String::from_utf16(u.as_slice()).unwrap();
1199
1200             assert!(::unicode::str::is_utf16(u.as_slice()));
1201             assert_eq!(s_as_utf16, u);
1202
1203             assert_eq!(u_as_string, s);
1204             assert_eq!(String::from_utf16_lossy(u.as_slice()), s);
1205
1206             assert_eq!(String::from_utf16(s_as_utf16.as_slice()).unwrap(), s);
1207             assert_eq!(u_as_string.utf16_units().collect::<Vec<u16>>(), u);
1208         }
1209     }
1210
1211     #[test]
1212     fn test_utf16_invalid() {
1213         // completely positive cases tested above.
1214         // lead + eof
1215         assert!(String::from_utf16(&[0xD800]).is_err());
1216         // lead + lead
1217         assert!(String::from_utf16(&[0xD800, 0xD800]).is_err());
1218
1219         // isolated trail
1220         assert!(String::from_utf16(&[0x0061, 0xDC00]).is_err());
1221
1222         // general
1223         assert!(String::from_utf16(&[0xD800, 0xd801, 0xdc8b, 0xD800]).is_err());
1224     }
1225
1226     #[test]
1227     fn test_from_utf16_lossy() {
1228         // completely positive cases tested above.
1229         // lead + eof
1230         assert_eq!(String::from_utf16_lossy(&[0xD800]), String::from_str("\u{FFFD}"));
1231         // lead + lead
1232         assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]),
1233                    String::from_str("\u{FFFD}\u{FFFD}"));
1234
1235         // isolated trail
1236         assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]), String::from_str("a\u{FFFD}"));
1237
1238         // general
1239         assert_eq!(String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
1240                    String::from_str("\u{FFFD}𐒋\u{FFFD}"));
1241     }
1242
1243     #[test]
1244     fn test_from_buf_len() {
1245         unsafe {
1246             let a = vec![65u8, 65, 65, 65, 65, 65, 65, 0];
1247             assert_eq!(super::raw::from_buf_len(a.as_ptr(), 3), String::from_str("AAA"));
1248         }
1249     }
1250
1251     #[test]
1252     fn test_from_buf() {
1253         unsafe {
1254             let a = vec![65, 65, 65, 65, 65, 65, 65, 0];
1255             let b = a.as_ptr();
1256             let c = super::raw::from_buf(b);
1257             assert_eq!(c, String::from_str("AAAAAAA"));
1258         }
1259     }
1260
1261     #[test]
1262     fn test_push_bytes() {
1263         let mut s = String::from_str("ABC");
1264         unsafe {
1265             let mv = s.as_mut_vec();
1266             mv.push_all(&[b'D']);
1267         }
1268         assert_eq!(s, "ABCD");
1269     }
1270
1271     #[test]
1272     fn test_push_str() {
1273         let mut s = String::new();
1274         s.push_str("");
1275         assert_eq!(s.slice_from(0), "");
1276         s.push_str("abc");
1277         assert_eq!(s.slice_from(0), "abc");
1278         s.push_str("ประเทศไทย中华Việt Nam");
1279         assert_eq!(s.slice_from(0), "abcประเทศไทย中华Việt Nam");
1280     }
1281
1282     #[test]
1283     fn test_push() {
1284         let mut data = String::from_str("ประเทศไทย中");
1285         data.push('华');
1286         data.push('b'); // 1 byte
1287         data.push('¢'); // 2 byte
1288         data.push('€'); // 3 byte
1289         data.push('𤭢'); // 4 byte
1290         assert_eq!(data, "ประเทศไทย中华b¢€𤭢");
1291     }
1292
1293     #[test]
1294     fn test_pop() {
1295         let mut data = String::from_str("ประเทศไทย中华b¢€𤭢");
1296         assert_eq!(data.pop().unwrap(), '𤭢'); // 4 bytes
1297         assert_eq!(data.pop().unwrap(), '€'); // 3 bytes
1298         assert_eq!(data.pop().unwrap(), '¢'); // 2 bytes
1299         assert_eq!(data.pop().unwrap(), 'b'); // 1 bytes
1300         assert_eq!(data.pop().unwrap(), '华');
1301         assert_eq!(data, "ประเทศไทย中");
1302     }
1303
1304     #[test]
1305     fn test_str_truncate() {
1306         let mut s = String::from_str("12345");
1307         s.truncate(5);
1308         assert_eq!(s, "12345");
1309         s.truncate(3);
1310         assert_eq!(s, "123");
1311         s.truncate(0);
1312         assert_eq!(s, "");
1313
1314         let mut s = String::from_str("12345");
1315         let p = s.as_ptr();
1316         s.truncate(3);
1317         s.push_str("6");
1318         let p_ = s.as_ptr();
1319         assert_eq!(p_, p);
1320     }
1321
1322     #[test]
1323     #[should_fail]
1324     fn test_str_truncate_invalid_len() {
1325         let mut s = String::from_str("12345");
1326         s.truncate(6);
1327     }
1328
1329     #[test]
1330     #[should_fail]
1331     fn test_str_truncate_split_codepoint() {
1332         let mut s = String::from_str("\u{FC}"); // ü
1333         s.truncate(1);
1334     }
1335
1336     #[test]
1337     fn test_str_clear() {
1338         let mut s = String::from_str("12345");
1339         s.clear();
1340         assert_eq!(s.len(), 0);
1341         assert_eq!(s, "");
1342     }
1343
1344     #[test]
1345     fn test_str_add() {
1346         let a = String::from_str("12345");
1347         let b = a + "2";
1348         let b = b + "2";
1349         assert_eq!(b.len(), 7);
1350         assert_eq!(b, "1234522");
1351     }
1352
1353     #[test]
1354     fn remove() {
1355         let mut s = "ศไทย中华Việt Nam; foobar".to_string();;
1356         assert_eq!(s.remove(0), 'ศ');
1357         assert_eq!(s.len(), 33);
1358         assert_eq!(s, "ไทย中华Việt Nam; foobar");
1359         assert_eq!(s.remove(17), 'ệ');
1360         assert_eq!(s, "ไทย中华Vit Nam; foobar");
1361     }
1362
1363     #[test] #[should_fail]
1364     fn remove_bad() {
1365         "ศ".to_string().remove(1);
1366     }
1367
1368     #[test]
1369     fn insert() {
1370         let mut s = "foobar".to_string();
1371         s.insert(0, 'ệ');
1372         assert_eq!(s, "ệfoobar");
1373         s.insert(6, 'ย');
1374         assert_eq!(s, "ệfooยbar");
1375     }
1376
1377     #[test] #[should_fail] fn insert_bad1() { "".to_string().insert(1, 't'); }
1378     #[test] #[should_fail] fn insert_bad2() { "ệ".to_string().insert(1, 't'); }
1379
1380     #[test]
1381     fn test_slicing() {
1382         let s = "foobar".to_string();
1383         assert_eq!("foobar", s[]);
1384         assert_eq!("foo", s[..3]);
1385         assert_eq!("bar", s[3..]);
1386         assert_eq!("oob", s[1..4]);
1387     }
1388
1389     #[test]
1390     fn test_simple_types() {
1391         assert_eq!(1i.to_string(), "1");
1392         assert_eq!((-1i).to_string(), "-1");
1393         assert_eq!(200u.to_string(), "200");
1394         assert_eq!(2u8.to_string(), "2");
1395         assert_eq!(true.to_string(), "true");
1396         assert_eq!(false.to_string(), "false");
1397         assert_eq!(().to_string(), "()");
1398         assert_eq!(("hi".to_string()).to_string(), "hi");
1399     }
1400
1401     #[test]
1402     fn test_vectors() {
1403         let x: Vec<int> = vec![];
1404         assert_eq!(x.to_string(), "[]");
1405         assert_eq!((vec![1i]).to_string(), "[1]");
1406         assert_eq!((vec![1i, 2, 3]).to_string(), "[1, 2, 3]");
1407         assert!((vec![vec![], vec![1i], vec![1i, 1]]).to_string() ==
1408                "[[], [1], [1, 1]]");
1409     }
1410
1411     #[test]
1412     fn test_from_iterator() {
1413         let s = "ศไทย中华Việt Nam".to_string();
1414         let t = "ศไทย中华";
1415         let u = "Việt Nam";
1416
1417         let a: String = s.chars().collect();
1418         assert_eq!(s, a);
1419
1420         let mut b = t.to_string();
1421         b.extend(u.chars());
1422         assert_eq!(s, b);
1423
1424         let c: String = vec![t, u].into_iter().collect();
1425         assert_eq!(s, c);
1426
1427         let mut d = t.to_string();
1428         d.extend(vec![u].into_iter());
1429         assert_eq!(s, d);
1430     }
1431
1432     #[bench]
1433     fn bench_with_capacity(b: &mut Bencher) {
1434         b.iter(|| {
1435             String::with_capacity(100)
1436         });
1437     }
1438
1439     #[bench]
1440     fn bench_push_str(b: &mut Bencher) {
1441         let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1442         b.iter(|| {
1443             let mut r = String::new();
1444             r.push_str(s);
1445         });
1446     }
1447
1448     const REPETITIONS: u64 = 10_000;
1449
1450     #[bench]
1451     fn bench_push_str_one_byte(b: &mut Bencher) {
1452         b.bytes = REPETITIONS;
1453         b.iter(|| {
1454             let mut r = String::new();
1455             for _ in range(0, REPETITIONS) {
1456                 r.push_str("a")
1457             }
1458         });
1459     }
1460
1461     #[bench]
1462     fn bench_push_char_one_byte(b: &mut Bencher) {
1463         b.bytes = REPETITIONS;
1464         b.iter(|| {
1465             let mut r = String::new();
1466             for _ in range(0, REPETITIONS) {
1467                 r.push('a')
1468             }
1469         });
1470     }
1471
1472     #[bench]
1473     fn bench_push_char_two_bytes(b: &mut Bencher) {
1474         b.bytes = REPETITIONS * 2;
1475         b.iter(|| {
1476             let mut r = String::new();
1477             for _ in range(0, REPETITIONS) {
1478                 r.push('â')
1479             }
1480         });
1481     }
1482
1483     #[bench]
1484     fn from_utf8_lossy_100_ascii(b: &mut Bencher) {
1485         let s = b"Hello there, the quick brown fox jumped over the lazy dog! \
1486                   Lorem ipsum dolor sit amet, consectetur. ";
1487
1488         assert_eq!(100, s.len());
1489         b.iter(|| {
1490             let _ = String::from_utf8_lossy(s);
1491         });
1492     }
1493
1494     #[bench]
1495     fn from_utf8_lossy_100_multibyte(b: &mut Bencher) {
1496         let s = "𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰".as_bytes();
1497         assert_eq!(100, s.len());
1498         b.iter(|| {
1499             let _ = String::from_utf8_lossy(s);
1500         });
1501     }
1502
1503     #[bench]
1504     fn from_utf8_lossy_invalid(b: &mut Bencher) {
1505         let s = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
1506         b.iter(|| {
1507             let _ = String::from_utf8_lossy(s);
1508         });
1509     }
1510
1511     #[bench]
1512     fn from_utf8_lossy_100_invalid(b: &mut Bencher) {
1513         let s = Vec::from_elem(100, 0xF5u8);
1514         b.iter(|| {
1515             let _ = String::from_utf8_lossy(s.as_slice());
1516         });
1517     }
1518 }