This commit performs another pass over the `std::char` module for stabilization.
Some minor cleanup is performed such as migrating documentation from libcore to
libunicode (where the `std`-facing trait resides) as well as a slight
reorganiation in libunicode itself. Otherwise, the stability modifications made
are:
* `char::from_digit` is now stable
* `CharExt::is_digit` is now stable
* `CharExt::to_digit` is now stable
* `CharExt::to_{lower,upper}case` are now stable after being modified to return
an iterator over characters. While the implementation today has not changed
this should allow us to implement the full set of case conversions in unicode
where some characters can map to multiple when doing an upper or lower case
mapping.
* `StrExt::to_{lower,upper}case` was added as unstable for a convenience of not
having to worry about characters expanding to more characters when you just
want the whole string to get into upper or lower case.
This is a breaking change due to the change in the signatures of the
`CharExt::to_{upper,lower}case` methods. Code can be updated to use functions
like `flat_map` or `collect` to handle the difference.
[breaking-change]
238 lines
6.4 KiB
Rust
238 lines
6.4 KiB
Rust
// 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.
|
||
//
|
||
// ignore-lexer-test FIXME #15679
|
||
|
||
#[test]
|
||
fn test_is_lowercase() {
|
||
assert!('a'.is_lowercase());
|
||
assert!('ö'.is_lowercase());
|
||
assert!('ß'.is_lowercase());
|
||
assert!(!'Ü'.is_lowercase());
|
||
assert!(!'P'.is_lowercase());
|
||
}
|
||
|
||
#[test]
|
||
fn test_is_uppercase() {
|
||
assert!(!'h'.is_uppercase());
|
||
assert!(!'ä'.is_uppercase());
|
||
assert!(!'ß'.is_uppercase());
|
||
assert!('Ö'.is_uppercase());
|
||
assert!('T'.is_uppercase());
|
||
}
|
||
|
||
#[test]
|
||
fn test_is_whitespace() {
|
||
assert!(' '.is_whitespace());
|
||
assert!('\u{2007}'.is_whitespace());
|
||
assert!('\t'.is_whitespace());
|
||
assert!('\n'.is_whitespace());
|
||
assert!(!'a'.is_whitespace());
|
||
assert!(!'_'.is_whitespace());
|
||
assert!(!'\u{0}'.is_whitespace());
|
||
}
|
||
|
||
#[test]
|
||
fn test_to_digit() {
|
||
assert_eq!('0'.to_digit(10), Some(0));
|
||
assert_eq!('1'.to_digit(2), Some(1));
|
||
assert_eq!('2'.to_digit(3), Some(2));
|
||
assert_eq!('9'.to_digit(10), Some(9));
|
||
assert_eq!('a'.to_digit(16), Some(10));
|
||
assert_eq!('A'.to_digit(16), Some(10));
|
||
assert_eq!('b'.to_digit(16), Some(11));
|
||
assert_eq!('B'.to_digit(16), Some(11));
|
||
assert_eq!('z'.to_digit(36), Some(35));
|
||
assert_eq!('Z'.to_digit(36), Some(35));
|
||
assert_eq!(' '.to_digit(10), None);
|
||
assert_eq!('$'.to_digit(36), None);
|
||
}
|
||
|
||
#[test]
|
||
fn test_to_lowercase() {
|
||
fn lower(c: char) -> char {
|
||
let mut it = c.to_lowercase();
|
||
let c = it.next().unwrap();
|
||
assert!(it.next().is_none());
|
||
c
|
||
}
|
||
assert_eq!(lower('A'), 'a');
|
||
assert_eq!(lower('Ö'), 'ö');
|
||
assert_eq!(lower('ß'), 'ß');
|
||
assert_eq!(lower('Ü'), 'ü');
|
||
assert_eq!(lower('💩'), '💩');
|
||
assert_eq!(lower('Σ'), 'σ');
|
||
assert_eq!(lower('Τ'), 'τ');
|
||
assert_eq!(lower('Ι'), 'ι');
|
||
assert_eq!(lower('Γ'), 'γ');
|
||
assert_eq!(lower('Μ'), 'μ');
|
||
assert_eq!(lower('Α'), 'α');
|
||
assert_eq!(lower('Σ'), 'σ');
|
||
}
|
||
|
||
#[test]
|
||
fn test_to_uppercase() {
|
||
fn upper(c: char) -> char {
|
||
let mut it = c.to_uppercase();
|
||
let c = it.next().unwrap();
|
||
assert!(it.next().is_none());
|
||
c
|
||
}
|
||
assert_eq!(upper('a'), 'A');
|
||
assert_eq!(upper('ö'), 'Ö');
|
||
assert_eq!(upper('ß'), 'ß'); // not ẞ: Latin capital letter sharp s
|
||
assert_eq!(upper('ü'), 'Ü');
|
||
assert_eq!(upper('💩'), '💩');
|
||
|
||
assert_eq!(upper('σ'), 'Σ');
|
||
assert_eq!(upper('τ'), 'Τ');
|
||
assert_eq!(upper('ι'), 'Ι');
|
||
assert_eq!(upper('γ'), 'Γ');
|
||
assert_eq!(upper('μ'), 'Μ');
|
||
assert_eq!(upper('α'), 'Α');
|
||
assert_eq!(upper('ς'), 'Σ');
|
||
}
|
||
|
||
#[test]
|
||
fn test_is_control() {
|
||
assert!('\u{0}'.is_control());
|
||
assert!('\u{3}'.is_control());
|
||
assert!('\u{6}'.is_control());
|
||
assert!('\u{9}'.is_control());
|
||
assert!('\u{7f}'.is_control());
|
||
assert!('\u{92}'.is_control());
|
||
assert!(!'\u{20}'.is_control());
|
||
assert!(!'\u{55}'.is_control());
|
||
assert!(!'\u{68}'.is_control());
|
||
}
|
||
|
||
#[test]
|
||
fn test_is_digit() {
|
||
assert!('2'.is_numeric());
|
||
assert!('7'.is_numeric());
|
||
assert!(!'c'.is_numeric());
|
||
assert!(!'i'.is_numeric());
|
||
assert!(!'z'.is_numeric());
|
||
assert!(!'Q'.is_numeric());
|
||
}
|
||
|
||
#[test]
|
||
fn test_escape_default() {
|
||
fn string(c: char) -> String {
|
||
c.escape_default().collect()
|
||
}
|
||
let s = string('\n');
|
||
assert_eq!(s, "\\n");
|
||
let s = string('\r');
|
||
assert_eq!(s, "\\r");
|
||
let s = string('\'');
|
||
assert_eq!(s, "\\'");
|
||
let s = string('"');
|
||
assert_eq!(s, "\\\"");
|
||
let s = string(' ');
|
||
assert_eq!(s, " ");
|
||
let s = string('a');
|
||
assert_eq!(s, "a");
|
||
let s = string('~');
|
||
assert_eq!(s, "~");
|
||
let s = string('\x00');
|
||
assert_eq!(s, "\\u{0}");
|
||
let s = string('\x1f');
|
||
assert_eq!(s, "\\u{1f}");
|
||
let s = string('\x7f');
|
||
assert_eq!(s, "\\u{7f}");
|
||
let s = string('\u{ff}');
|
||
assert_eq!(s, "\\u{ff}");
|
||
let s = string('\u{11b}');
|
||
assert_eq!(s, "\\u{11b}");
|
||
let s = string('\u{1d4b6}');
|
||
assert_eq!(s, "\\u{1d4b6}");
|
||
}
|
||
|
||
#[test]
|
||
fn test_escape_unicode() {
|
||
fn string(c: char) -> String { c.escape_unicode().collect() }
|
||
|
||
let s = string('\x00');
|
||
assert_eq!(s, "\\u{0}");
|
||
let s = string('\n');
|
||
assert_eq!(s, "\\u{a}");
|
||
let s = string(' ');
|
||
assert_eq!(s, "\\u{20}");
|
||
let s = string('a');
|
||
assert_eq!(s, "\\u{61}");
|
||
let s = string('\u{11b}');
|
||
assert_eq!(s, "\\u{11b}");
|
||
let s = string('\u{1d4b6}');
|
||
assert_eq!(s, "\\u{1d4b6}");
|
||
}
|
||
|
||
#[test]
|
||
fn test_encode_utf8() {
|
||
fn check(input: char, expect: &[u8]) {
|
||
let mut buf = [0; 4];
|
||
let n = input.encode_utf8(&mut buf).unwrap_or(0);
|
||
assert_eq!(&buf[..n], expect);
|
||
}
|
||
|
||
check('x', &[0x78]);
|
||
check('\u{e9}', &[0xc3, 0xa9]);
|
||
check('\u{a66e}', &[0xea, 0x99, 0xae]);
|
||
check('\u{1f4a9}', &[0xf0, 0x9f, 0x92, 0xa9]);
|
||
}
|
||
|
||
#[test]
|
||
fn test_encode_utf16() {
|
||
fn check(input: char, expect: &[u16]) {
|
||
let mut buf = [0; 2];
|
||
let n = input.encode_utf16(&mut buf).unwrap_or(0);
|
||
assert_eq!(&buf[..n], expect);
|
||
}
|
||
|
||
check('x', &[0x0078]);
|
||
check('\u{e9}', &[0x00e9]);
|
||
check('\u{a66e}', &[0xa66e]);
|
||
check('\u{1f4a9}', &[0xd83d, 0xdca9]);
|
||
}
|
||
|
||
#[test]
|
||
fn test_len_utf16() {
|
||
assert!('x'.len_utf16() == 1);
|
||
assert!('\u{e9}'.len_utf16() == 1);
|
||
assert!('\u{a66e}'.len_utf16() == 1);
|
||
assert!('\u{1f4a9}'.len_utf16() == 2);
|
||
}
|
||
|
||
#[test]
|
||
fn test_width() {
|
||
assert_eq!('\x00'.width(false),Some(0));
|
||
assert_eq!('\x00'.width(true),Some(0));
|
||
|
||
assert_eq!('\x0A'.width(false),None);
|
||
assert_eq!('\x0A'.width(true),None);
|
||
|
||
assert_eq!('w'.width(false),Some(1));
|
||
assert_eq!('w'.width(true),Some(1));
|
||
|
||
assert_eq!('h'.width(false),Some(2));
|
||
assert_eq!('h'.width(true),Some(2));
|
||
|
||
assert_eq!('\u{AD}'.width(false),Some(1));
|
||
assert_eq!('\u{AD}'.width(true),Some(1));
|
||
|
||
assert_eq!('\u{1160}'.width(false),Some(0));
|
||
assert_eq!('\u{1160}'.width(true),Some(0));
|
||
|
||
assert_eq!('\u{a1}'.width(false),Some(1));
|
||
assert_eq!('\u{a1}'.width(true),Some(2));
|
||
|
||
assert_eq!('\u{300}'.width(false),Some(0));
|
||
assert_eq!('\u{300}'.width(true),Some(0));
|
||
}
|