2015-03-10 23:58:16 -05:00
|
|
|
|
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
|
//
|
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
|
// except according to those terms.
|
|
|
|
|
|
2016-01-30 16:19:37 -08:00
|
|
|
|
use std::borrow::Cow;
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
2016-01-30 16:19:37 -08:00
|
|
|
|
pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
|
|
|
|
|
fn into_cow(self) -> Cow<'a, B>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a> IntoCow<'a, str> for String {
|
|
|
|
|
fn into_cow(self) -> Cow<'a, str> {
|
|
|
|
|
Cow::Owned(self)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a> IntoCow<'a, str> for &'a str {
|
|
|
|
|
fn into_cow(self) -> Cow<'a, str> {
|
|
|
|
|
Cow::Borrowed(self)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-10 23:58:16 -05:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_from_str() {
|
2016-05-22 23:57:13 +05:30
|
|
|
|
let owned: Option<::std::string::String> = "string".parse().ok();
|
|
|
|
|
assert_eq!(owned.as_ref().map(|s| &**s), Some("string"));
|
2015-03-10 23:58:16 -05:00
|
|
|
|
}
|
|
|
|
|
|
Implement `From<Cow<str>> for String` and `From<Cow<[T]>> for Vec<T>`.
Motivation: the `selectors` crate is generic over a string type,
in order to support all of `String`, `string_cache::Atom`, and
`gecko_string_cache::Atom`. Multiple trait bounds are used
for the various operations done with these strings.
One of these operations is creating a string (as efficiently as possible,
re-using an existing memory allocation if possible) from `Cow<str>`.
The `std::convert::From` trait seems natural for this, but
the relevant implementation was missing before this PR.
To work around this I’ve added a `FromCowStr` trait in `selectors`,
but with trait coherence that means one of `selectors` or `string_cache`
needs to depend on the other to implement this trait.
Using a trait from `std` would solve this.
The `Vec<T>` implementation is just added for consistency.
I also tried a more general
`impl<'a, O, B: ?Sized + ToOwned<Owned=O>> From<Cow<'a, B>> for O`,
but (the compiler thinks?) it conflicts with `From<T> for T` the impl
(after moving all of `collections::borrow` into `core::borrow`
to work around trait coherence).
2016-10-21 16:51:59 +02:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_from_cow_str() {
|
|
|
|
|
assert_eq!(String::from(Cow::Borrowed("string")), "string");
|
|
|
|
|
assert_eq!(String::from(Cow::Owned(String::from("string"))), "string");
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-10 23:58:16 -05:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_unsized_to_string() {
|
|
|
|
|
let s: &str = "abc";
|
|
|
|
|
let _: String = (*s).to_string();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_from_utf8() {
|
|
|
|
|
let xs = b"hello".to_vec();
|
2016-05-22 23:57:13 +05:30
|
|
|
|
assert_eq!(String::from_utf8(xs).unwrap(), String::from("hello"));
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
|
|
let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
|
|
|
|
|
assert_eq!(String::from_utf8(xs).unwrap(),
|
2015-06-08 16:55:35 +02:00
|
|
|
|
String::from("ศไทย中华Việt Nam"));
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
|
|
let xs = b"hello\xFF".to_vec();
|
2016-05-06 19:32:18 -04:00
|
|
|
|
let err = String::from_utf8(xs).unwrap_err();
|
2015-03-10 23:58:16 -05:00
|
|
|
|
assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_from_utf8_lossy() {
|
|
|
|
|
let xs = b"hello";
|
2015-03-30 11:00:05 -07:00
|
|
|
|
let ys: Cow<str> = "hello".into_cow();
|
2015-03-10 23:58:16 -05:00
|
|
|
|
assert_eq!(String::from_utf8_lossy(xs), ys);
|
|
|
|
|
|
|
|
|
|
let xs = "ศไทย中华Việt Nam".as_bytes();
|
2015-03-30 11:00:05 -07:00
|
|
|
|
let ys: Cow<str> = "ศไทย中华Việt Nam".into_cow();
|
2015-03-10 23:58:16 -05:00
|
|
|
|
assert_eq!(String::from_utf8_lossy(xs), ys);
|
|
|
|
|
|
|
|
|
|
let xs = b"Hello\xC2 There\xFF Goodbye";
|
|
|
|
|
assert_eq!(String::from_utf8_lossy(xs),
|
2015-06-08 16:55:35 +02:00
|
|
|
|
String::from("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow());
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
|
|
let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
|
|
|
|
|
assert_eq!(String::from_utf8_lossy(xs),
|
2015-06-08 16:55:35 +02:00
|
|
|
|
String::from("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow());
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
|
|
let xs = b"\xF5foo\xF5\x80bar";
|
|
|
|
|
assert_eq!(String::from_utf8_lossy(xs),
|
2015-06-08 16:55:35 +02:00
|
|
|
|
String::from("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow());
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
|
|
let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
|
|
|
|
|
assert_eq!(String::from_utf8_lossy(xs),
|
2015-06-08 16:55:35 +02:00
|
|
|
|
String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow());
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
|
|
let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
|
|
|
|
|
assert_eq!(String::from_utf8_lossy(xs),
|
2015-06-08 16:55:35 +02:00
|
|
|
|
String::from("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow());
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
|
|
let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
|
2016-05-22 23:57:13 +05:30
|
|
|
|
assert_eq!(String::from_utf8_lossy(xs),
|
|
|
|
|
String::from("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}foo\u{10000}bar").into_cow());
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
|
|
// surrogates
|
|
|
|
|
let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
|
2016-05-22 23:57:13 +05:30
|
|
|
|
assert_eq!(String::from_utf8_lossy(xs),
|
|
|
|
|
String::from("\u{FFFD}\u{FFFD}\u{FFFD}foo\u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow());
|
2015-03-10 23:58:16 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_from_utf16() {
|
2016-05-22 23:57:13 +05:30
|
|
|
|
let pairs = [(String::from("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
|
|
|
|
|
vec![0xd800, 0xdf45, 0xd800, 0xdf3f, 0xd800, 0xdf3b, 0xd800, 0xdf46, 0xd800,
|
|
|
|
|
0xdf39, 0xd800, 0xdf3b, 0xd800, 0xdf30, 0x000a]),
|
|
|
|
|
|
|
|
|
|
(String::from("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
|
|
|
|
|
vec![0xd801, 0xdc12, 0xd801, 0xdc49, 0xd801, 0xdc2e, 0xd801, 0xdc40, 0xd801,
|
|
|
|
|
0xdc32, 0xd801, 0xdc4b, 0x0020, 0xd801, 0xdc0f, 0xd801, 0xdc32, 0xd801,
|
|
|
|
|
0xdc4d, 0x000a]),
|
|
|
|
|
|
|
|
|
|
(String::from("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
|
|
|
|
|
vec![0xd800, 0xdf00, 0xd800, 0xdf16, 0xd800, 0xdf0b, 0xd800, 0xdf04, 0xd800,
|
|
|
|
|
0xdf11, 0xd800, 0xdf09, 0x00b7, 0xd800, 0xdf0c, 0xd800, 0xdf04, 0xd800,
|
|
|
|
|
0xdf15, 0xd800, 0xdf04, 0xd800, 0xdf0b, 0xd800, 0xdf09, 0xd800, 0xdf11,
|
|
|
|
|
0x000a]),
|
|
|
|
|
|
|
|
|
|
(String::from("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
|
|
|
|
|
vec![0xd801, 0xdc8b, 0xd801, 0xdc98, 0xd801, 0xdc88, 0xd801, 0xdc91, 0xd801,
|
|
|
|
|
0xdc9b, 0xd801, 0xdc92, 0x0020, 0xd801, 0xdc95, 0xd801, 0xdc93, 0x0020,
|
|
|
|
|
0xd801, 0xdc88, 0xd801, 0xdc9a, 0xd801, 0xdc8d, 0x0020, 0xd801, 0xdc8f,
|
|
|
|
|
0xd801, 0xdc9c, 0xd801, 0xdc92, 0xd801, 0xdc96, 0xd801, 0xdc86, 0x0020,
|
|
|
|
|
0xd801, 0xdc95, 0xd801, 0xdc86, 0x000a]),
|
|
|
|
|
// Issue #12318, even-numbered non-BMP planes
|
|
|
|
|
(String::from("\u{20000}"), vec![0xD840, 0xDC00])];
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
|
|
for p in &pairs {
|
|
|
|
|
let (s, u) = (*p).clone();
|
std: Stabilize APIs for the 1.8 release
This commit is the result of the FCPs ending for the 1.8 release cycle for both
the libs and the lang suteams. The full list of changes are:
Stabilized
* `braced_empty_structs`
* `augmented_assignments`
* `str::encode_utf16` - renamed from `utf16_units`
* `str::EncodeUtf16` - renamed from `Utf16Units`
* `Ref::map`
* `RefMut::map`
* `ptr::drop_in_place`
* `time::Instant`
* `time::SystemTime`
* `{Instant,SystemTime}::now`
* `{Instant,SystemTime}::duration_since` - renamed from `duration_from_earlier`
* `{Instant,SystemTime}::elapsed`
* Various `Add`/`Sub` impls for `Time` and `SystemTime`
* `SystemTimeError`
* `SystemTimeError::duration`
* Various impls for `SystemTimeError`
* `UNIX_EPOCH`
* `ops::{Add,Sub,Mul,Div,Rem,BitAnd,BitOr,BitXor,Shl,Shr}Assign`
Deprecated
* Scoped TLS (the `scoped_thread_local!` macro)
* `Ref::filter_map`
* `RefMut::filter_map`
* `RwLockReadGuard::map`
* `RwLockWriteGuard::map`
* `Condvar::wait_timeout_with`
Closes #27714
Closes #27715
Closes #27746
Closes #27748
Closes #27908
Closes #29866
2016-02-25 15:52:29 -08:00
|
|
|
|
let s_as_utf16 = s.encode_utf16().collect::<Vec<u16>>();
|
2015-03-10 23:58:16 -05:00
|
|
|
|
let u_as_string = String::from_utf16(&u).unwrap();
|
|
|
|
|
|
2017-03-01 23:01:09 +01:00
|
|
|
|
assert!(::std_unicode::char::decode_utf16(u.iter().cloned()).all(|r| r.is_ok()));
|
2015-03-10 23:58:16 -05:00
|
|
|
|
assert_eq!(s_as_utf16, u);
|
|
|
|
|
|
|
|
|
|
assert_eq!(u_as_string, s);
|
|
|
|
|
assert_eq!(String::from_utf16_lossy(&u), s);
|
|
|
|
|
|
|
|
|
|
assert_eq!(String::from_utf16(&s_as_utf16).unwrap(), s);
|
std: Stabilize APIs for the 1.8 release
This commit is the result of the FCPs ending for the 1.8 release cycle for both
the libs and the lang suteams. The full list of changes are:
Stabilized
* `braced_empty_structs`
* `augmented_assignments`
* `str::encode_utf16` - renamed from `utf16_units`
* `str::EncodeUtf16` - renamed from `Utf16Units`
* `Ref::map`
* `RefMut::map`
* `ptr::drop_in_place`
* `time::Instant`
* `time::SystemTime`
* `{Instant,SystemTime}::now`
* `{Instant,SystemTime}::duration_since` - renamed from `duration_from_earlier`
* `{Instant,SystemTime}::elapsed`
* Various `Add`/`Sub` impls for `Time` and `SystemTime`
* `SystemTimeError`
* `SystemTimeError::duration`
* Various impls for `SystemTimeError`
* `UNIX_EPOCH`
* `ops::{Add,Sub,Mul,Div,Rem,BitAnd,BitOr,BitXor,Shl,Shr}Assign`
Deprecated
* Scoped TLS (the `scoped_thread_local!` macro)
* `Ref::filter_map`
* `RefMut::filter_map`
* `RwLockReadGuard::map`
* `RwLockWriteGuard::map`
* `Condvar::wait_timeout_with`
Closes #27714
Closes #27715
Closes #27746
Closes #27748
Closes #27908
Closes #29866
2016-02-25 15:52:29 -08:00
|
|
|
|
assert_eq!(u_as_string.encode_utf16().collect::<Vec<u16>>(), u);
|
2015-03-10 23:58:16 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_utf16_invalid() {
|
|
|
|
|
// completely positive cases tested above.
|
|
|
|
|
// lead + eof
|
|
|
|
|
assert!(String::from_utf16(&[0xD800]).is_err());
|
|
|
|
|
// lead + lead
|
|
|
|
|
assert!(String::from_utf16(&[0xD800, 0xD800]).is_err());
|
|
|
|
|
|
|
|
|
|
// isolated trail
|
|
|
|
|
assert!(String::from_utf16(&[0x0061, 0xDC00]).is_err());
|
|
|
|
|
|
|
|
|
|
// general
|
|
|
|
|
assert!(String::from_utf16(&[0xD800, 0xd801, 0xdc8b, 0xD800]).is_err());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_from_utf16_lossy() {
|
|
|
|
|
// completely positive cases tested above.
|
|
|
|
|
// lead + eof
|
2016-05-22 23:57:13 +05:30
|
|
|
|
assert_eq!(String::from_utf16_lossy(&[0xD800]),
|
|
|
|
|
String::from("\u{FFFD}"));
|
2015-03-10 23:58:16 -05:00
|
|
|
|
// lead + lead
|
|
|
|
|
assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]),
|
2015-06-08 16:55:35 +02:00
|
|
|
|
String::from("\u{FFFD}\u{FFFD}"));
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
|
|
// isolated trail
|
2016-05-22 23:57:13 +05:30
|
|
|
|
assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]),
|
|
|
|
|
String::from("a\u{FFFD}"));
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
|
|
// general
|
|
|
|
|
assert_eq!(String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
|
2015-06-08 16:55:35 +02:00
|
|
|
|
String::from("\u{FFFD}𐒋\u{FFFD}"));
|
2015-03-10 23:58:16 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_push_bytes() {
|
2015-06-08 16:55:35 +02:00
|
|
|
|
let mut s = String::from("ABC");
|
2015-03-10 23:58:16 -05:00
|
|
|
|
unsafe {
|
|
|
|
|
let mv = s.as_mut_vec();
|
2016-01-30 16:19:37 -08:00
|
|
|
|
mv.extend_from_slice(&[b'D']);
|
2015-03-10 23:58:16 -05:00
|
|
|
|
}
|
|
|
|
|
assert_eq!(s, "ABCD");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_push_str() {
|
|
|
|
|
let mut s = String::new();
|
|
|
|
|
s.push_str("");
|
|
|
|
|
assert_eq!(&s[0..], "");
|
|
|
|
|
s.push_str("abc");
|
|
|
|
|
assert_eq!(&s[0..], "abc");
|
|
|
|
|
s.push_str("ประเทศไทย中华Việt Nam");
|
|
|
|
|
assert_eq!(&s[0..], "abcประเทศไทย中华Việt Nam");
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-27 02:30:50 +08:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_add_assign() {
|
|
|
|
|
let mut s = String::new();
|
|
|
|
|
s += "";
|
|
|
|
|
assert_eq!(s.as_str(), "");
|
|
|
|
|
s += "abc";
|
|
|
|
|
assert_eq!(s.as_str(), "abc");
|
|
|
|
|
s += "ประเทศไทย中华Việt Nam";
|
|
|
|
|
assert_eq!(s.as_str(), "abcประเทศไทย中华Việt Nam");
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-10 23:58:16 -05:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_push() {
|
2015-06-08 16:55:35 +02:00
|
|
|
|
let mut data = String::from("ประเทศไทย中");
|
2015-03-10 23:58:16 -05:00
|
|
|
|
data.push('华');
|
|
|
|
|
data.push('b'); // 1 byte
|
|
|
|
|
data.push('¢'); // 2 byte
|
|
|
|
|
data.push('€'); // 3 byte
|
|
|
|
|
data.push('𤭢'); // 4 byte
|
|
|
|
|
assert_eq!(data, "ประเทศไทย中华b¢€𤭢");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_pop() {
|
2015-06-08 16:55:35 +02:00
|
|
|
|
let mut data = String::from("ประเทศไทย中华b¢€𤭢");
|
2015-03-10 23:58:16 -05:00
|
|
|
|
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(), '华');
|
|
|
|
|
assert_eq!(data, "ประเทศไทย中");
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-28 13:54:55 -05:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_split_off_empty() {
|
|
|
|
|
let orig = "Hello, world!";
|
|
|
|
|
let mut split = String::from(orig);
|
|
|
|
|
let empty: String = split.split_off(orig.len());
|
|
|
|
|
assert!(empty.is_empty());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[should_panic]
|
|
|
|
|
fn test_split_off_past_end() {
|
|
|
|
|
let orig = "Hello, world!";
|
|
|
|
|
let mut split = String::from(orig);
|
|
|
|
|
split.split_off(orig.len() + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[should_panic]
|
|
|
|
|
fn test_split_off_mid_char() {
|
|
|
|
|
let mut orig = String::from("山");
|
|
|
|
|
orig.split_off(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_split_off_ascii() {
|
|
|
|
|
let mut ab = String::from("ABCD");
|
|
|
|
|
let cd = ab.split_off(2);
|
|
|
|
|
assert_eq!(ab, "AB");
|
|
|
|
|
assert_eq!(cd, "CD");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_split_off_unicode() {
|
|
|
|
|
let mut nihon = String::from("日本語");
|
|
|
|
|
let go = nihon.split_off("日本".len());
|
|
|
|
|
assert_eq!(nihon, "日本");
|
|
|
|
|
assert_eq!(go, "語");
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-10 23:58:16 -05:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_str_truncate() {
|
2015-06-08 16:55:35 +02:00
|
|
|
|
let mut s = String::from("12345");
|
2015-03-10 23:58:16 -05:00
|
|
|
|
s.truncate(5);
|
|
|
|
|
assert_eq!(s, "12345");
|
|
|
|
|
s.truncate(3);
|
|
|
|
|
assert_eq!(s, "123");
|
|
|
|
|
s.truncate(0);
|
|
|
|
|
assert_eq!(s, "");
|
|
|
|
|
|
2015-06-08 16:55:35 +02:00
|
|
|
|
let mut s = String::from("12345");
|
2015-03-10 23:58:16 -05:00
|
|
|
|
let p = s.as_ptr();
|
|
|
|
|
s.truncate(3);
|
|
|
|
|
s.push_str("6");
|
|
|
|
|
let p_ = s.as_ptr();
|
|
|
|
|
assert_eq!(p_, p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_str_truncate_invalid_len() {
|
2015-06-08 16:55:35 +02:00
|
|
|
|
let mut s = String::from("12345");
|
2015-03-10 23:58:16 -05:00
|
|
|
|
s.truncate(6);
|
2016-04-14 16:56:59 -07:00
|
|
|
|
assert_eq!(s, "12345");
|
2015-03-10 23:58:16 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[should_panic]
|
|
|
|
|
fn test_str_truncate_split_codepoint() {
|
2015-06-08 16:55:35 +02:00
|
|
|
|
let mut s = String::from("\u{FC}"); // ü
|
2015-03-10 23:58:16 -05:00
|
|
|
|
s.truncate(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_str_clear() {
|
2015-06-08 16:55:35 +02:00
|
|
|
|
let mut s = String::from("12345");
|
2015-03-10 23:58:16 -05:00
|
|
|
|
s.clear();
|
|
|
|
|
assert_eq!(s.len(), 0);
|
|
|
|
|
assert_eq!(s, "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_str_add() {
|
2015-06-08 16:55:35 +02:00
|
|
|
|
let a = String::from("12345");
|
2015-03-10 23:58:16 -05:00
|
|
|
|
let b = a + "2";
|
|
|
|
|
let b = b + "2";
|
|
|
|
|
assert_eq!(b.len(), 7);
|
|
|
|
|
assert_eq!(b, "1234522");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn remove() {
|
2015-09-27 20:26:12 -06:00
|
|
|
|
let mut s = "ศไทย中华Việt Nam; foobar".to_string();
|
2015-03-10 23:58:16 -05:00
|
|
|
|
assert_eq!(s.remove(0), 'ศ');
|
|
|
|
|
assert_eq!(s.len(), 33);
|
|
|
|
|
assert_eq!(s, "ไทย中华Việt Nam; foobar");
|
|
|
|
|
assert_eq!(s.remove(17), 'ệ');
|
|
|
|
|
assert_eq!(s, "ไทย中华Vit Nam; foobar");
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-22 23:57:13 +05:30
|
|
|
|
#[test]
|
|
|
|
|
#[should_panic]
|
2015-03-10 23:58:16 -05:00
|
|
|
|
fn remove_bad() {
|
|
|
|
|
"ศ".to_string().remove(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn insert() {
|
|
|
|
|
let mut s = "foobar".to_string();
|
|
|
|
|
s.insert(0, 'ệ');
|
|
|
|
|
assert_eq!(s, "ệfoobar");
|
|
|
|
|
s.insert(6, 'ย');
|
|
|
|
|
assert_eq!(s, "ệfooยbar");
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-22 23:57:13 +05:30
|
|
|
|
#[test]
|
|
|
|
|
#[should_panic]
|
|
|
|
|
fn insert_bad1() {
|
|
|
|
|
"".to_string().insert(1, 't');
|
|
|
|
|
}
|
|
|
|
|
#[test]
|
|
|
|
|
#[should_panic]
|
|
|
|
|
fn insert_bad2() {
|
|
|
|
|
"ệ".to_string().insert(1, 't');
|
|
|
|
|
}
|
2015-03-10 23:58:16 -05:00
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_slicing() {
|
|
|
|
|
let s = "foobar".to_string();
|
|
|
|
|
assert_eq!("foobar", &s[..]);
|
|
|
|
|
assert_eq!("foo", &s[..3]);
|
|
|
|
|
assert_eq!("bar", &s[3..]);
|
|
|
|
|
assert_eq!("oob", &s[1..4]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_simple_types() {
|
|
|
|
|
assert_eq!(1.to_string(), "1");
|
|
|
|
|
assert_eq!((-1).to_string(), "-1");
|
|
|
|
|
assert_eq!(200.to_string(), "200");
|
|
|
|
|
assert_eq!(2.to_string(), "2");
|
|
|
|
|
assert_eq!(true.to_string(), "true");
|
|
|
|
|
assert_eq!(false.to_string(), "false");
|
|
|
|
|
assert_eq!(("hi".to_string()).to_string(), "hi");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_vectors() {
|
|
|
|
|
let x: Vec<i32> = vec![];
|
|
|
|
|
assert_eq!(format!("{:?}", x), "[]");
|
|
|
|
|
assert_eq!(format!("{:?}", vec![1]), "[1]");
|
|
|
|
|
assert_eq!(format!("{:?}", vec![1, 2, 3]), "[1, 2, 3]");
|
2016-05-22 23:57:13 +05:30
|
|
|
|
assert!(format!("{:?}", vec![vec![], vec![1], vec![1, 1]]) == "[[], [1], [1, 1]]");
|
2015-03-10 23:58:16 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[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();
|
|
|
|
|
assert_eq!(s, a);
|
|
|
|
|
|
|
|
|
|
let mut b = t.to_string();
|
|
|
|
|
b.extend(u.chars());
|
|
|
|
|
assert_eq!(s, b);
|
|
|
|
|
|
|
|
|
|
let c: String = vec![t, u].into_iter().collect();
|
|
|
|
|
assert_eq!(s, c);
|
|
|
|
|
|
|
|
|
|
let mut d = t.to_string();
|
2015-06-10 17:22:20 +01:00
|
|
|
|
d.extend(vec![u]);
|
2015-03-10 23:58:16 -05:00
|
|
|
|
assert_eq!(s, d);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-01 15:34:25 +02:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_drain() {
|
|
|
|
|
let mut s = String::from("αβγ");
|
|
|
|
|
assert_eq!(s.drain(2..4).collect::<String>(), "β");
|
|
|
|
|
assert_eq!(s, "αγ");
|
|
|
|
|
|
|
|
|
|
let mut t = String::from("abcd");
|
|
|
|
|
t.drain(..0);
|
|
|
|
|
assert_eq!(t, "abcd");
|
|
|
|
|
t.drain(..1);
|
|
|
|
|
assert_eq!(t, "bcd");
|
|
|
|
|
t.drain(3..);
|
|
|
|
|
assert_eq!(t, "bcd");
|
|
|
|
|
t.drain(..);
|
|
|
|
|
assert_eq!(t, "");
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-03 12:38:42 +02:00
|
|
|
|
#[test]
|
|
|
|
|
fn test_extend_ref() {
|
|
|
|
|
let mut a = "foo".to_string();
|
|
|
|
|
a.extend(&['b', 'a', 'r']);
|
|
|
|
|
|
|
|
|
|
assert_eq!(&a, "foobar");
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-10 00:04:06 -07:00
|
|
|
|
#[test]
|
2015-08-13 14:02:00 +02:00
|
|
|
|
fn test_into_boxed_str() {
|
2015-07-10 00:04:06 -07:00
|
|
|
|
let xs = String::from("hello my name is bob");
|
2015-08-13 14:02:00 +02:00
|
|
|
|
let ys = xs.into_boxed_str();
|
2015-07-10 00:04:06 -07:00
|
|
|
|
assert_eq!(&*ys, "hello my name is bob");
|
|
|
|
|
}
|