2014-05-25 19:12:43 -05:00
|
|
|
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
2012-12-03 18:48:01 -06:00
|
|
|
// 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.
|
|
|
|
|
Add libunicode; move unicode functions from core
- created new crate, libunicode, below libstd
- split Char trait into Char (libcore) and UnicodeChar (libunicode)
- Unicode-aware functions now live in libunicode
- is_alphabetic, is_XID_start, is_XID_continue, is_lowercase,
is_uppercase, is_whitespace, is_alphanumeric, is_control,
is_digit, to_uppercase, to_lowercase
- added width method in UnicodeChar trait
- determines printed width of character in columns, or None if it is
a non-NULL control character
- takes a boolean argument indicating whether the present context is
CJK or not (characters with 'A'mbiguous widths are double-wide in
CJK contexts, single-wide otherwise)
- split StrSlice into StrSlice (libcore) and UnicodeStrSlice
(libunicode)
- functionality formerly in StrSlice that relied upon Unicode
functionality from Char is now in UnicodeStrSlice
- words, is_whitespace, is_alphanumeric, trim, trim_left, trim_right
- also moved Words type alias into libunicode because words method is
in UnicodeStrSlice
- unified Unicode tables from libcollections, libcore, and libregex into
libunicode
- updated unicode.py in src/etc to generate aforementioned tables
- generated new tables based on latest Unicode data
- added UnicodeChar and UnicodeStrSlice traits to prelude
- libunicode is now the collection point for the std::char module,
combining the libunicode functionality with the Char functionality
from libcore
- thus, moved doc comment for char from core::char to unicode::char
- libcollections remains the collection point for std::str
The Unicode-aware functions that previously lived in the Char and
StrSlice traits are no longer available to programs that only use
libcore. To regain use of these methods, include the libunicode crate
and use the UnicodeChar and/or UnicodeStrSlice traits:
extern crate unicode;
use unicode::UnicodeChar;
use unicode::UnicodeStrSlice;
use unicode::Words; // if you want to use the words() method
NOTE: this does *not* impact programs that use libstd, since UnicodeChar
and UnicodeStrSlice have been added to the prelude.
closes #15224
[breaking-change]
2014-06-30 16:04:10 -05:00
|
|
|
//! Character manipulation.
|
2014-03-07 16:53:34 -06:00
|
|
|
//!
|
Add libunicode; move unicode functions from core
- created new crate, libunicode, below libstd
- split Char trait into Char (libcore) and UnicodeChar (libunicode)
- Unicode-aware functions now live in libunicode
- is_alphabetic, is_XID_start, is_XID_continue, is_lowercase,
is_uppercase, is_whitespace, is_alphanumeric, is_control,
is_digit, to_uppercase, to_lowercase
- added width method in UnicodeChar trait
- determines printed width of character in columns, or None if it is
a non-NULL control character
- takes a boolean argument indicating whether the present context is
CJK or not (characters with 'A'mbiguous widths are double-wide in
CJK contexts, single-wide otherwise)
- split StrSlice into StrSlice (libcore) and UnicodeStrSlice
(libunicode)
- functionality formerly in StrSlice that relied upon Unicode
functionality from Char is now in UnicodeStrSlice
- words, is_whitespace, is_alphanumeric, trim, trim_left, trim_right
- also moved Words type alias into libunicode because words method is
in UnicodeStrSlice
- unified Unicode tables from libcollections, libcore, and libregex into
libunicode
- updated unicode.py in src/etc to generate aforementioned tables
- generated new tables based on latest Unicode data
- added UnicodeChar and UnicodeStrSlice traits to prelude
- libunicode is now the collection point for the std::char module,
combining the libunicode functionality with the Char functionality
from libcore
- thus, moved doc comment for char from core::char to unicode::char
- libcollections remains the collection point for std::str
The Unicode-aware functions that previously lived in the Char and
StrSlice traits are no longer available to programs that only use
libcore. To regain use of these methods, include the libunicode crate
and use the UnicodeChar and/or UnicodeStrSlice traits:
extern crate unicode;
use unicode::UnicodeChar;
use unicode::UnicodeStrSlice;
use unicode::Words; // if you want to use the words() method
NOTE: this does *not* impact programs that use libstd, since UnicodeChar
and UnicodeStrSlice have been added to the prelude.
closes #15224
[breaking-change]
2014-06-30 16:04:10 -05:00
|
|
|
//! For more details, see ::unicode::char (a.k.a. std::char)
|
2014-03-07 16:53:34 -06:00
|
|
|
|
2014-07-18 07:45:17 -05:00
|
|
|
#![allow(non_snake_case)]
|
2014-05-28 21:53:37 -05:00
|
|
|
#![doc(primitive = "char")]
|
2011-12-13 18:25:51 -06:00
|
|
|
|
2014-12-15 10:49:01 -06:00
|
|
|
use iter::Iterator;
|
core: Remove the cast module
This commit revisits the `cast` module in libcore and libstd, and scrutinizes
all functions inside of it. The result was to remove the `cast` module entirely,
folding all functionality into the `mem` module. Specifically, this is the fate
of each function in the `cast` module.
* transmute - This function was moved to `mem`, but it is now marked as
#[unstable]. This is due to planned changes to the `transmute`
function and how it can be invoked (see the #[unstable] comment).
For more information, see RFC 5 and #12898
* transmute_copy - This function was moved to `mem`, with clarification that is
is not an error to invoke it with T/U that are different
sizes, but rather that it is strongly discouraged. This
function is now #[stable]
* forget - This function was moved to `mem` and marked #[stable]
* bump_box_refcount - This function was removed due to the deprecation of
managed boxes as well as its questionable utility.
* transmute_mut - This function was previously deprecated, and removed as part
of this commit.
* transmute_mut_unsafe - This function doesn't serve much of a purpose when it
can be achieved with an `as` in safe code, so it was
removed.
* transmute_lifetime - This function was removed because it is likely a strong
indication that code is incorrect in the first place.
* transmute_mut_lifetime - This function was removed for the same reasons as
`transmute_lifetime`
* copy_lifetime - This function was moved to `mem`, but it is marked
`#[unstable]` now due to the likelihood of being removed in
the future if it is found to not be very useful.
* copy_mut_lifetime - This function was also moved to `mem`, but had the same
treatment as `copy_lifetime`.
* copy_lifetime_vec - This function was removed because it is not used today,
and its existence is not necessary with DST
(copy_lifetime will suffice).
In summary, the cast module was stripped down to these functions, and then the
functions were moved to the `mem` module.
transmute - #[unstable]
transmute_copy - #[stable]
forget - #[stable]
copy_lifetime - #[unstable]
copy_mut_lifetime - #[unstable]
[breaking-change]
2014-05-09 12:34:51 -05:00
|
|
|
use mem::transmute;
|
2014-12-05 12:53:25 -06:00
|
|
|
use ops::FnMut;
|
2014-11-28 10:57:41 -06:00
|
|
|
use option::Option::{None, Some};
|
2014-12-15 10:49:01 -06:00
|
|
|
use option::Option;
|
2014-12-11 11:44:17 -06:00
|
|
|
use slice::SliceExt;
|
2014-07-21 22:54:28 -05:00
|
|
|
|
2013-08-10 02:28:47 -05:00
|
|
|
// UTF-8 ranges and tags for encoding characters
|
2014-05-12 14:53:53 -05:00
|
|
|
static TAG_CONT: u8 = 0b1000_0000u8;
|
|
|
|
static TAG_TWO_B: u8 = 0b1100_0000u8;
|
|
|
|
static TAG_THREE_B: u8 = 0b1110_0000u8;
|
|
|
|
static TAG_FOUR_B: u8 = 0b1111_0000u8;
|
|
|
|
static MAX_ONE_B: u32 = 0x80u32;
|
|
|
|
static MAX_TWO_B: u32 = 0x800u32;
|
|
|
|
static MAX_THREE_B: u32 = 0x10000u32;
|
2013-08-10 02:28:47 -05:00
|
|
|
|
2011-12-23 20:48:08 -06:00
|
|
|
/*
|
2013-05-18 14:53:30 -05:00
|
|
|
Lu Uppercase_Letter an uppercase letter
|
|
|
|
Ll Lowercase_Letter a lowercase letter
|
|
|
|
Lt Titlecase_Letter a digraphic character, with first part uppercase
|
|
|
|
Lm Modifier_Letter a modifier letter
|
|
|
|
Lo Other_Letter other letters, including syllables and ideographs
|
|
|
|
Mn Nonspacing_Mark a nonspacing combining mark (zero advance width)
|
|
|
|
Mc Spacing_Mark a spacing combining mark (positive advance width)
|
|
|
|
Me Enclosing_Mark an enclosing combining mark
|
|
|
|
Nd Decimal_Number a decimal digit
|
|
|
|
Nl Letter_Number a letterlike numeric character
|
|
|
|
No Other_Number a numeric character of other type
|
2011-12-23 20:48:08 -06:00
|
|
|
Pc Connector_Punctuation a connecting punctuation mark, like a tie
|
2013-05-18 14:53:30 -05:00
|
|
|
Pd Dash_Punctuation a dash or hyphen punctuation mark
|
|
|
|
Ps Open_Punctuation an opening punctuation mark (of a pair)
|
|
|
|
Pe Close_Punctuation a closing punctuation mark (of a pair)
|
2011-12-23 20:48:08 -06:00
|
|
|
Pi Initial_Punctuation an initial quotation mark
|
2013-05-18 14:53:30 -05:00
|
|
|
Pf Final_Punctuation a final quotation mark
|
|
|
|
Po Other_Punctuation a punctuation mark of other type
|
|
|
|
Sm Math_Symbol a symbol of primarily mathematical use
|
|
|
|
Sc Currency_Symbol a currency sign
|
|
|
|
Sk Modifier_Symbol a non-letterlike modifier symbol
|
|
|
|
So Other_Symbol a symbol of other type
|
|
|
|
Zs Space_Separator a space character (of various non-zero widths)
|
|
|
|
Zl Line_Separator U+2028 LINE SEPARATOR only
|
2011-12-23 20:48:08 -06:00
|
|
|
Zp Paragraph_Separator U+2029 PARAGRAPH SEPARATOR only
|
2013-05-18 14:53:30 -05:00
|
|
|
Cc Control a C0 or C1 control code
|
|
|
|
Cf Format a format control character
|
|
|
|
Cs Surrogate a surrogate code point
|
|
|
|
Co Private_Use a private-use character
|
|
|
|
Cn Unassigned a reserved unassigned code point or a noncharacter
|
2011-12-23 20:48:08 -06:00
|
|
|
*/
|
|
|
|
|
2013-09-03 18:24:12 -05:00
|
|
|
/// The highest valid code point
|
2014-10-08 19:06:19 -05:00
|
|
|
#[stable]
|
2014-12-09 16:08:10 -06:00
|
|
|
pub const MAX: char = '\u{10ffff}';
|
2013-09-03 18:24:12 -05:00
|
|
|
|
2014-03-07 17:13:54 -06:00
|
|
|
/// Converts from `u32` to a `char`
|
2014-02-22 16:11:36 -06:00
|
|
|
#[inline]
|
2014-10-10 16:55:11 -05:00
|
|
|
#[unstable = "pending decisions about costructors for primitives"]
|
2013-09-03 18:24:12 -05:00
|
|
|
pub fn from_u32(i: u32) -> Option<char> {
|
|
|
|
// catch out-of-bounds and surrogates
|
|
|
|
if (i > MAX as u32) || (i >= 0xD800 && i <= 0xDFFF) {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(unsafe { transmute(i) })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-18 15:03:40 -05:00
|
|
|
///
|
2014-03-07 17:13:54 -06:00
|
|
|
/// Checks if a `char` parses as a numeric digit in the given radix
|
|
|
|
///
|
2014-11-26 17:42:54 -06:00
|
|
|
/// Compared to `is_numeric()`, this function only recognizes the
|
2013-05-18 15:03:40 -05:00
|
|
|
/// characters `0-9`, `a-z` and `A-Z`.
|
|
|
|
///
|
|
|
|
/// # Return value
|
|
|
|
///
|
|
|
|
/// Returns `true` if `c` is a valid digit under `radix`, and `false`
|
|
|
|
/// otherwise.
|
|
|
|
///
|
2014-11-11 12:36:09 -06:00
|
|
|
/// # Panics
|
2013-05-18 15:03:40 -05:00
|
|
|
///
|
2014-11-11 12:36:09 -06:00
|
|
|
/// Panics if given a `radix` > 36.
|
2013-05-18 15:03:40 -05:00
|
|
|
///
|
|
|
|
/// # Note
|
|
|
|
///
|
|
|
|
/// This just wraps `to_digit()`.
|
|
|
|
///
|
2013-06-18 16:45:18 -05:00
|
|
|
#[inline]
|
2014-10-13 12:54:18 -05:00
|
|
|
#[deprecated = "use the Char::is_digit method"]
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn is_digit_radix(c: char, radix: uint) -> bool {
|
2014-10-13 15:03:42 -05:00
|
|
|
c.is_digit(radix)
|
2013-01-20 14:28:12 -06:00
|
|
|
}
|
|
|
|
|
2013-05-18 15:03:40 -05:00
|
|
|
///
|
2014-03-07 17:13:54 -06:00
|
|
|
/// Converts a `char` to the corresponding digit
|
2013-05-18 15:03:40 -05:00
|
|
|
///
|
|
|
|
/// # Return value
|
|
|
|
///
|
|
|
|
/// If `c` is between '0' and '9', the corresponding value
|
|
|
|
/// between 0 and 9. If `c` is 'a' or 'A', 10. If `c` is
|
2014-03-07 16:53:34 -06:00
|
|
|
/// 'b' or 'B', 11, etc. Returns none if the `char` does not
|
2013-05-18 15:03:40 -05:00
|
|
|
/// refer to a digit in the given radix.
|
|
|
|
///
|
2014-11-11 12:36:09 -06:00
|
|
|
/// # Panics
|
2013-05-18 15:03:40 -05:00
|
|
|
///
|
2014-11-11 12:36:09 -06:00
|
|
|
/// Panics if given a `radix` outside the range `[0..36]`.
|
2013-05-18 15:03:40 -05:00
|
|
|
///
|
2013-01-13 08:37:30 -06:00
|
|
|
#[inline]
|
2014-10-13 12:54:18 -05:00
|
|
|
#[deprecated = "use the Char::to_digit method"]
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn to_digit(c: char, radix: uint) -> Option<uint> {
|
2014-10-13 15:03:42 -05:00
|
|
|
c.to_digit(radix)
|
2011-12-13 18:25:51 -06:00
|
|
|
}
|
|
|
|
|
2013-05-18 15:03:40 -05:00
|
|
|
///
|
2014-03-07 17:13:54 -06:00
|
|
|
/// Converts a number to the character representing it
|
2013-05-18 15:03:40 -05:00
|
|
|
///
|
|
|
|
/// # Return value
|
|
|
|
///
|
|
|
|
/// Returns `Some(char)` if `num` represents one digit under `radix`,
|
|
|
|
/// using one character of `0-9` or `a-z`, or `None` if it doesn't.
|
|
|
|
///
|
2014-11-11 12:36:09 -06:00
|
|
|
/// # Panics
|
2013-05-18 15:03:40 -05:00
|
|
|
///
|
2014-11-11 12:36:09 -06:00
|
|
|
/// Panics if given an `radix` > 36.
|
2013-05-18 15:03:40 -05:00
|
|
|
///
|
2013-01-20 14:28:12 -06:00
|
|
|
#[inline]
|
2014-10-10 16:55:11 -05:00
|
|
|
#[unstable = "pending decisions about costructors for primitives"]
|
2013-03-21 23:20:48 -05:00
|
|
|
pub fn from_digit(num: uint, radix: uint) -> Option<char> {
|
2013-01-20 14:28:12 -06:00
|
|
|
if radix > 36 {
|
2014-12-13 23:48:09 -06:00
|
|
|
panic!("from_digit: radix is too high (maximum 36)");
|
2013-01-20 14:28:12 -06:00
|
|
|
}
|
|
|
|
if num < radix {
|
2013-09-03 18:24:12 -05:00
|
|
|
unsafe {
|
|
|
|
if num < 10 {
|
|
|
|
Some(transmute(('0' as uint + num) as u32))
|
|
|
|
} else {
|
|
|
|
Some(transmute(('a' as uint + num - 10u) as u32))
|
|
|
|
}
|
2013-01-20 14:28:12 -06:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-15 10:49:01 -06:00
|
|
|
/// Deprecated, call the escape_unicode method instead.
|
2014-10-13 12:54:18 -05:00
|
|
|
#[deprecated = "use the Char::escape_unicode method"]
|
2014-12-05 12:53:25 -06:00
|
|
|
pub fn escape_unicode<F>(c: char, mut f: F) where F: FnMut(char) {
|
2014-10-31 18:20:41 -05:00
|
|
|
for char in c.escape_unicode() {
|
|
|
|
f(char);
|
|
|
|
}
|
2012-05-31 17:31:13 -05:00
|
|
|
}
|
|
|
|
|
2014-12-15 10:49:01 -06:00
|
|
|
/// Deprecated, call the escape_default method instead.
|
2014-10-13 12:54:18 -05:00
|
|
|
#[deprecated = "use the Char::escape_default method"]
|
2014-12-05 12:53:25 -06:00
|
|
|
pub fn escape_default<F>(c: char, mut f: F) where F: FnMut(char) {
|
2014-10-31 18:20:41 -05:00
|
|
|
for c in c.escape_default() {
|
|
|
|
f(c);
|
|
|
|
}
|
2012-05-31 17:31:13 -05:00
|
|
|
}
|
|
|
|
|
2014-03-07 16:53:34 -06:00
|
|
|
/// Returns the amount of bytes this `char` would need if encoded in UTF-8
|
2014-08-13 18:02:31 -05:00
|
|
|
#[inline]
|
2014-10-13 12:54:18 -05:00
|
|
|
#[deprecated = "use the Char::len_utf8 method"]
|
2013-05-18 14:53:30 -05:00
|
|
|
pub fn len_utf8_bytes(c: char) -> uint {
|
2014-10-13 15:03:42 -05:00
|
|
|
c.len_utf8()
|
2013-05-18 14:53:30 -05:00
|
|
|
}
|
|
|
|
|
Add libunicode; move unicode functions from core
- created new crate, libunicode, below libstd
- split Char trait into Char (libcore) and UnicodeChar (libunicode)
- Unicode-aware functions now live in libunicode
- is_alphabetic, is_XID_start, is_XID_continue, is_lowercase,
is_uppercase, is_whitespace, is_alphanumeric, is_control,
is_digit, to_uppercase, to_lowercase
- added width method in UnicodeChar trait
- determines printed width of character in columns, or None if it is
a non-NULL control character
- takes a boolean argument indicating whether the present context is
CJK or not (characters with 'A'mbiguous widths are double-wide in
CJK contexts, single-wide otherwise)
- split StrSlice into StrSlice (libcore) and UnicodeStrSlice
(libunicode)
- functionality formerly in StrSlice that relied upon Unicode
functionality from Char is now in UnicodeStrSlice
- words, is_whitespace, is_alphanumeric, trim, trim_left, trim_right
- also moved Words type alias into libunicode because words method is
in UnicodeStrSlice
- unified Unicode tables from libcollections, libcore, and libregex into
libunicode
- updated unicode.py in src/etc to generate aforementioned tables
- generated new tables based on latest Unicode data
- added UnicodeChar and UnicodeStrSlice traits to prelude
- libunicode is now the collection point for the std::char module,
combining the libunicode functionality with the Char functionality
from libcore
- thus, moved doc comment for char from core::char to unicode::char
- libcollections remains the collection point for std::str
The Unicode-aware functions that previously lived in the Char and
StrSlice traits are no longer available to programs that only use
libcore. To regain use of these methods, include the libunicode crate
and use the UnicodeChar and/or UnicodeStrSlice traits:
extern crate unicode;
use unicode::UnicodeChar;
use unicode::UnicodeStrSlice;
use unicode::Words; // if you want to use the words() method
NOTE: this does *not* impact programs that use libstd, since UnicodeChar
and UnicodeStrSlice have been added to the prelude.
closes #15224
[breaking-change]
2014-06-30 16:04:10 -05:00
|
|
|
/// Basic `char` manipulations.
|
2014-10-08 19:05:12 -05:00
|
|
|
#[experimental = "trait organization may change"]
|
2013-05-18 14:50:02 -05:00
|
|
|
pub trait Char {
|
2014-03-16 17:59:04 -05:00
|
|
|
/// Checks if a `char` parses as a numeric digit in the given radix.
|
|
|
|
///
|
2014-11-26 17:42:54 -06:00
|
|
|
/// Compared to `is_numeric()`, this function only recognizes the characters
|
2014-03-16 17:59:04 -05:00
|
|
|
/// `0-9`, `a-z` and `A-Z`.
|
|
|
|
///
|
|
|
|
/// # Return value
|
|
|
|
///
|
|
|
|
/// Returns `true` if `c` is a valid digit under `radix`, and `false`
|
|
|
|
/// otherwise.
|
|
|
|
///
|
2014-11-11 12:36:09 -06:00
|
|
|
/// # Panics
|
2014-03-16 17:59:04 -05:00
|
|
|
///
|
2014-11-11 12:36:09 -06:00
|
|
|
/// Panics if given a radix > 36.
|
2014-10-08 19:24:15 -05:00
|
|
|
#[deprecated = "use is_digit"]
|
2014-10-14 15:08:54 -05:00
|
|
|
fn is_digit_radix(self, radix: uint) -> bool;
|
2014-03-16 17:59:04 -05:00
|
|
|
|
2014-10-08 19:24:15 -05:00
|
|
|
/// Checks if a `char` parses as a numeric digit in the given radix.
|
|
|
|
///
|
2014-11-26 17:42:54 -06:00
|
|
|
/// Compared to `is_numeric()`, this function only recognizes the characters
|
2014-10-08 19:24:15 -05:00
|
|
|
/// `0-9`, `a-z` and `A-Z`.
|
|
|
|
///
|
|
|
|
/// # Return value
|
|
|
|
///
|
|
|
|
/// Returns `true` if `c` is a valid digit under `radix`, and `false`
|
|
|
|
/// otherwise.
|
|
|
|
///
|
2014-11-05 20:17:27 -06:00
|
|
|
/// # Panics
|
2014-10-08 19:24:15 -05:00
|
|
|
///
|
2014-11-05 20:17:27 -06:00
|
|
|
/// Panics if given a radix > 36.
|
2014-10-13 12:57:49 -05:00
|
|
|
#[unstable = "pending error conventions"]
|
2014-10-14 15:08:54 -05:00
|
|
|
fn is_digit(self, radix: uint) -> bool;
|
2014-10-08 19:24:15 -05:00
|
|
|
|
2014-03-16 17:59:04 -05:00
|
|
|
/// Converts a character to the corresponding digit.
|
|
|
|
///
|
|
|
|
/// # Return value
|
|
|
|
///
|
|
|
|
/// If `c` is between '0' and '9', the corresponding value between 0 and
|
|
|
|
/// 9. If `c` is 'a' or 'A', 10. If `c` is 'b' or 'B', 11, etc. Returns
|
|
|
|
/// none if the character does not refer to a digit in the given radix.
|
|
|
|
///
|
2014-11-11 12:36:09 -06:00
|
|
|
/// # Panics
|
2014-03-16 17:59:04 -05:00
|
|
|
///
|
2014-11-11 12:36:09 -06:00
|
|
|
/// Panics if given a radix outside the range [0..36].
|
2014-10-13 12:57:49 -05:00
|
|
|
#[unstable = "pending error conventions, trait organization"]
|
2014-10-14 15:08:54 -05:00
|
|
|
fn to_digit(self, radix: uint) -> Option<uint>;
|
2014-03-16 17:59:04 -05:00
|
|
|
|
|
|
|
/// Converts a number to the character representing it.
|
|
|
|
///
|
|
|
|
/// # Return value
|
|
|
|
///
|
|
|
|
/// Returns `Some(char)` if `num` represents one digit under `radix`,
|
|
|
|
/// using one character of `0-9` or `a-z`, or `None` if it doesn't.
|
|
|
|
///
|
2014-11-11 12:36:09 -06:00
|
|
|
/// # Panics
|
2014-03-16 17:59:04 -05:00
|
|
|
///
|
2014-11-11 12:36:09 -06:00
|
|
|
/// Panics if given a radix > 36.
|
2014-10-10 16:55:11 -05:00
|
|
|
#[deprecated = "use the char::from_digit free function"]
|
2014-08-06 20:46:54 -05:00
|
|
|
fn from_digit(num: uint, radix: uint) -> Option<Self>;
|
2014-03-16 17:59:04 -05:00
|
|
|
|
2014-10-08 19:03:04 -05:00
|
|
|
/// Converts from `u32` to a `char`
|
2014-10-10 16:55:11 -05:00
|
|
|
#[deprecated = "use the char::from_u32 free function"]
|
2014-10-08 19:03:04 -05:00
|
|
|
fn from_u32(i: u32) -> Option<char>;
|
|
|
|
|
2014-11-05 19:50:09 -06:00
|
|
|
/// Returns an iterator that yields the hexadecimal Unicode escape
|
|
|
|
/// of a character, as `char`s.
|
2014-03-16 17:59:04 -05:00
|
|
|
///
|
2014-12-15 10:49:01 -06:00
|
|
|
/// All characters are escaped with Rust syntax of the form `\\u{NNNN}`
|
|
|
|
/// where `NNNN` is the shortest hexadecimal representation of the code
|
|
|
|
/// point.
|
2014-10-13 12:57:49 -05:00
|
|
|
#[unstable = "pending error conventions, trait organization"]
|
2014-12-15 10:49:01 -06:00
|
|
|
fn escape_unicode(self) -> EscapeUnicode;
|
2014-03-16 17:59:04 -05:00
|
|
|
|
2014-11-05 19:50:09 -06:00
|
|
|
/// Returns an iterator that yields the 'default' ASCII and
|
|
|
|
/// C++11-like literal escape of a character, as `char`s.
|
2014-03-16 17:59:04 -05:00
|
|
|
///
|
|
|
|
/// The default is chosen with a bias toward producing literals that are
|
|
|
|
/// legal in a variety of languages, including C++11 and similar C-family
|
|
|
|
/// languages. The exact rules are:
|
|
|
|
///
|
|
|
|
/// * Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
|
|
|
|
/// * Single-quote, double-quote and backslash chars are backslash-
|
|
|
|
/// escaped.
|
|
|
|
/// * Any other chars in the range [0x20,0x7e] are not escaped.
|
2014-09-02 00:35:58 -05:00
|
|
|
/// * Any other chars are given hex Unicode escapes; see `escape_unicode`.
|
2014-10-13 12:57:49 -05:00
|
|
|
#[unstable = "pending error conventions, trait organization"]
|
2014-12-15 10:49:01 -06:00
|
|
|
fn escape_default(self) -> EscapeDefault;
|
2014-03-16 17:59:04 -05:00
|
|
|
|
|
|
|
/// Returns the amount of bytes this character would need if encoded in
|
|
|
|
/// UTF-8.
|
2014-10-08 19:33:02 -05:00
|
|
|
#[deprecated = "use len_utf8"]
|
2014-10-14 15:08:54 -05:00
|
|
|
fn len_utf8_bytes(self) -> uint;
|
2013-08-10 02:28:47 -05:00
|
|
|
|
2014-10-08 19:33:02 -05:00
|
|
|
/// Returns the amount of bytes this character would need if encoded in
|
|
|
|
/// UTF-8.
|
2014-10-13 12:57:49 -05:00
|
|
|
#[unstable = "pending trait organization"]
|
2014-10-14 15:08:54 -05:00
|
|
|
fn len_utf8(self) -> uint;
|
2014-10-08 19:33:02 -05:00
|
|
|
|
2014-10-08 19:40:31 -05:00
|
|
|
/// Returns the amount of bytes this character would need if encoded in
|
|
|
|
/// UTF-16.
|
2014-10-13 12:57:49 -05:00
|
|
|
#[unstable = "pending trait organization"]
|
2014-10-14 15:08:54 -05:00
|
|
|
fn len_utf16(self) -> uint;
|
2014-10-08 19:40:31 -05:00
|
|
|
|
2014-08-13 18:02:31 -05:00
|
|
|
/// Encodes this character as UTF-8 into the provided byte buffer,
|
|
|
|
/// and then returns the number of bytes written.
|
2013-08-10 02:28:47 -05:00
|
|
|
///
|
2014-08-13 18:02:31 -05:00
|
|
|
/// If the buffer is not large enough, nothing will be written into it
|
|
|
|
/// and a `None` will be returned.
|
2014-10-13 12:57:49 -05:00
|
|
|
#[unstable = "pending trait organization"]
|
2014-08-13 18:02:31 -05:00
|
|
|
fn encode_utf8(&self, dst: &mut [u8]) -> Option<uint>;
|
2014-04-11 14:49:31 -05:00
|
|
|
|
2014-08-13 18:02:31 -05:00
|
|
|
/// Encodes this character as UTF-16 into the provided `u16` buffer,
|
|
|
|
/// and then returns the number of `u16`s written.
|
2014-04-11 14:49:31 -05:00
|
|
|
///
|
2014-08-13 18:02:31 -05:00
|
|
|
/// If the buffer is not large enough, nothing will be written into it
|
|
|
|
/// and a `None` will be returned.
|
2014-10-13 12:57:49 -05:00
|
|
|
#[unstable = "pending trait organization"]
|
2014-08-13 18:02:31 -05:00
|
|
|
fn encode_utf16(&self, dst: &mut [u16]) -> Option<uint>;
|
2013-05-18 14:50:02 -05:00
|
|
|
}
|
|
|
|
|
2014-10-08 19:05:12 -05:00
|
|
|
#[experimental = "trait is experimental"]
|
2013-05-18 14:50:02 -05:00
|
|
|
impl Char for char {
|
2014-10-08 19:24:15 -05:00
|
|
|
#[deprecated = "use is_digit"]
|
2014-10-14 15:08:54 -05:00
|
|
|
fn is_digit_radix(self, radix: uint) -> bool { self.is_digit(radix) }
|
2013-05-18 14:50:02 -05:00
|
|
|
|
2014-10-13 12:57:49 -05:00
|
|
|
#[unstable = "pending trait organization"]
|
2014-10-14 15:08:54 -05:00
|
|
|
fn is_digit(self, radix: uint) -> bool {
|
2014-10-13 15:03:42 -05:00
|
|
|
match self.to_digit(radix) {
|
|
|
|
Some(_) => true,
|
|
|
|
None => false,
|
|
|
|
}
|
|
|
|
}
|
2014-10-08 19:24:15 -05:00
|
|
|
|
2014-10-13 12:57:49 -05:00
|
|
|
#[unstable = "pending trait organization"]
|
2014-10-14 15:08:54 -05:00
|
|
|
fn to_digit(self, radix: uint) -> Option<uint> {
|
2014-10-13 15:03:42 -05:00
|
|
|
if radix > 36 {
|
|
|
|
panic!("to_digit: radix is too high (maximum 36)");
|
|
|
|
}
|
2014-10-14 15:08:54 -05:00
|
|
|
let val = match self {
|
|
|
|
'0' ... '9' => self as uint - ('0' as uint),
|
|
|
|
'a' ... 'z' => self as uint + 10u - ('a' as uint),
|
|
|
|
'A' ... 'Z' => self as uint + 10u - ('A' as uint),
|
2014-10-13 15:03:42 -05:00
|
|
|
_ => return None,
|
|
|
|
};
|
|
|
|
if val < radix { Some(val) }
|
|
|
|
else { None }
|
|
|
|
}
|
2013-05-18 14:50:02 -05:00
|
|
|
|
2014-10-10 16:55:11 -05:00
|
|
|
#[deprecated = "use the char::from_digit free function"]
|
2013-05-18 14:50:02 -05:00
|
|
|
fn from_digit(num: uint, radix: uint) -> Option<char> { from_digit(num, radix) }
|
|
|
|
|
2014-10-08 19:03:04 -05:00
|
|
|
#[inline]
|
2014-10-10 16:55:11 -05:00
|
|
|
#[deprecated = "use the char::from_u32 free function"]
|
2014-10-08 19:03:04 -05:00
|
|
|
fn from_u32(i: u32) -> Option<char> { from_u32(i) }
|
|
|
|
|
2014-10-13 12:57:49 -05:00
|
|
|
#[unstable = "pending error conventions, trait organization"]
|
2014-12-15 10:49:01 -06:00
|
|
|
fn escape_unicode(self) -> EscapeUnicode {
|
|
|
|
EscapeUnicode { c: self, state: EscapeUnicodeState::Backslash }
|
2014-10-13 15:03:42 -05:00
|
|
|
}
|
2013-05-18 14:50:02 -05:00
|
|
|
|
2014-10-13 12:57:49 -05:00
|
|
|
#[unstable = "pending error conventions, trait organization"]
|
2014-12-15 10:49:01 -06:00
|
|
|
fn escape_default(self) -> EscapeDefault {
|
2014-10-31 18:20:41 -05:00
|
|
|
let init_state = match self {
|
2014-12-15 10:49:01 -06:00
|
|
|
'\t' => EscapeDefaultState::Backslash('t'),
|
|
|
|
'\r' => EscapeDefaultState::Backslash('r'),
|
|
|
|
'\n' => EscapeDefaultState::Backslash('n'),
|
|
|
|
'\\' => EscapeDefaultState::Backslash('\\'),
|
|
|
|
'\'' => EscapeDefaultState::Backslash('\''),
|
|
|
|
'"' => EscapeDefaultState::Backslash('"'),
|
|
|
|
'\x20' ... '\x7e' => EscapeDefaultState::Char(self),
|
|
|
|
_ => EscapeDefaultState::Unicode(self.escape_unicode())
|
2014-10-31 18:20:41 -05:00
|
|
|
};
|
2014-12-15 10:49:01 -06:00
|
|
|
EscapeDefault { state: init_state }
|
2014-10-13 15:03:42 -05:00
|
|
|
}
|
2013-05-18 14:50:02 -05:00
|
|
|
|
2014-08-13 18:02:31 -05:00
|
|
|
#[inline]
|
2014-10-08 19:33:02 -05:00
|
|
|
#[deprecated = "use len_utf8"]
|
2014-10-14 15:08:54 -05:00
|
|
|
fn len_utf8_bytes(self) -> uint { self.len_utf8() }
|
2013-08-10 02:28:47 -05:00
|
|
|
|
2014-10-08 19:33:02 -05:00
|
|
|
#[inline]
|
2014-10-13 12:57:49 -05:00
|
|
|
#[unstable = "pending trait organization"]
|
2014-10-14 15:08:54 -05:00
|
|
|
fn len_utf8(self) -> uint {
|
|
|
|
let code = self as u32;
|
2014-10-13 15:03:42 -05:00
|
|
|
match () {
|
|
|
|
_ if code < MAX_ONE_B => 1u,
|
|
|
|
_ if code < MAX_TWO_B => 2u,
|
|
|
|
_ if code < MAX_THREE_B => 3u,
|
|
|
|
_ => 4u,
|
|
|
|
}
|
|
|
|
}
|
2014-10-08 19:33:02 -05:00
|
|
|
|
2014-10-08 19:40:31 -05:00
|
|
|
#[inline]
|
2014-10-13 12:57:49 -05:00
|
|
|
#[unstable = "pending trait organization"]
|
2014-10-14 15:08:54 -05:00
|
|
|
fn len_utf16(self) -> uint {
|
|
|
|
let ch = self as u32;
|
2014-10-08 19:40:31 -05:00
|
|
|
if (ch & 0xFFFF_u32) == ch { 1 } else { 2 }
|
|
|
|
}
|
|
|
|
|
2014-08-13 18:02:31 -05:00
|
|
|
#[inline]
|
2014-10-13 12:57:49 -05:00
|
|
|
#[unstable = "pending error conventions, trait organization"]
|
2014-08-13 18:02:31 -05:00
|
|
|
fn encode_utf8<'a>(&self, dst: &'a mut [u8]) -> Option<uint> {
|
|
|
|
// Marked #[inline] to allow llvm optimizing it away
|
2014-05-12 14:53:53 -05:00
|
|
|
let code = *self as u32;
|
2014-08-13 18:02:31 -05:00
|
|
|
if code < MAX_ONE_B && dst.len() >= 1 {
|
2013-08-10 02:28:47 -05:00
|
|
|
dst[0] = code as u8;
|
2014-08-13 18:02:31 -05:00
|
|
|
Some(1)
|
|
|
|
} else if code < MAX_TWO_B && dst.len() >= 2 {
|
2014-05-12 14:53:53 -05:00
|
|
|
dst[0] = (code >> 6u & 0x1F_u32) as u8 | TAG_TWO_B;
|
|
|
|
dst[1] = (code & 0x3F_u32) as u8 | TAG_CONT;
|
2014-08-13 18:02:31 -05:00
|
|
|
Some(2)
|
|
|
|
} else if code < MAX_THREE_B && dst.len() >= 3 {
|
2014-05-12 14:53:53 -05:00
|
|
|
dst[0] = (code >> 12u & 0x0F_u32) as u8 | TAG_THREE_B;
|
|
|
|
dst[1] = (code >> 6u & 0x3F_u32) as u8 | TAG_CONT;
|
|
|
|
dst[2] = (code & 0x3F_u32) as u8 | TAG_CONT;
|
2014-08-13 18:02:31 -05:00
|
|
|
Some(3)
|
|
|
|
} else if dst.len() >= 4 {
|
2014-05-12 14:53:53 -05:00
|
|
|
dst[0] = (code >> 18u & 0x07_u32) as u8 | TAG_FOUR_B;
|
|
|
|
dst[1] = (code >> 12u & 0x3F_u32) as u8 | TAG_CONT;
|
|
|
|
dst[2] = (code >> 6u & 0x3F_u32) as u8 | TAG_CONT;
|
|
|
|
dst[3] = (code & 0x3F_u32) as u8 | TAG_CONT;
|
2014-08-13 18:02:31 -05:00
|
|
|
Some(4)
|
|
|
|
} else {
|
|
|
|
None
|
2013-08-10 02:28:47 -05:00
|
|
|
}
|
|
|
|
}
|
2014-04-11 14:49:31 -05:00
|
|
|
|
2014-08-13 18:02:31 -05:00
|
|
|
#[inline]
|
2014-10-13 12:57:49 -05:00
|
|
|
#[unstable = "pending error conventions, trait organization"]
|
2014-08-13 18:02:31 -05:00
|
|
|
fn encode_utf16(&self, dst: &mut [u16]) -> Option<uint> {
|
|
|
|
// Marked #[inline] to allow llvm optimizing it away
|
2014-05-12 14:53:53 -05:00
|
|
|
let mut ch = *self as u32;
|
2014-08-13 18:02:31 -05:00
|
|
|
if (ch & 0xFFFF_u32) == ch && dst.len() >= 1 {
|
2014-05-12 14:53:53 -05:00
|
|
|
// The BMP falls through (assuming non-surrogate, as it should)
|
2014-04-11 14:49:31 -05:00
|
|
|
dst[0] = ch as u16;
|
2014-08-13 18:02:31 -05:00
|
|
|
Some(1)
|
|
|
|
} else if dst.len() >= 2 {
|
2014-04-11 14:49:31 -05:00
|
|
|
// Supplementary planes break into surrogates.
|
2014-05-12 14:53:53 -05:00
|
|
|
ch -= 0x1_0000_u32;
|
2014-04-11 14:49:31 -05:00
|
|
|
dst[0] = 0xD800_u16 | ((ch >> 10) as u16);
|
|
|
|
dst[1] = 0xDC00_u16 | ((ch as u16) & 0x3FF_u16);
|
2014-08-13 18:02:31 -05:00
|
|
|
Some(2)
|
|
|
|
} else {
|
|
|
|
None
|
2014-04-11 14:49:31 -05:00
|
|
|
}
|
|
|
|
}
|
2013-05-18 14:50:02 -05:00
|
|
|
}
|
2014-10-31 18:20:41 -05:00
|
|
|
|
|
|
|
/// An iterator over the characters that represent a `char`, as escaped by
|
|
|
|
/// Rust's unicode escaping rules.
|
2014-12-30 04:01:36 -06:00
|
|
|
#[deriving(Clone)]
|
2014-12-15 10:49:01 -06:00
|
|
|
pub struct EscapeUnicode {
|
2014-10-31 18:20:41 -05:00
|
|
|
c: char,
|
2014-12-15 10:49:01 -06:00
|
|
|
state: EscapeUnicodeState
|
2014-10-31 18:20:41 -05:00
|
|
|
}
|
|
|
|
|
2014-12-30 04:01:36 -06:00
|
|
|
#[deriving(Clone)]
|
2014-12-15 10:49:01 -06:00
|
|
|
enum EscapeUnicodeState {
|
2014-10-31 18:20:41 -05:00
|
|
|
Backslash,
|
|
|
|
Type,
|
2014-12-15 10:49:01 -06:00
|
|
|
LeftBrace,
|
|
|
|
Value(uint),
|
|
|
|
RightBrace,
|
|
|
|
Done,
|
2014-10-31 18:20:41 -05:00
|
|
|
}
|
|
|
|
|
2014-12-29 15:18:41 -06:00
|
|
|
impl Iterator for EscapeUnicode {
|
|
|
|
type Item = char;
|
|
|
|
|
2014-10-31 18:20:41 -05:00
|
|
|
fn next(&mut self) -> Option<char> {
|
|
|
|
match self.state {
|
2014-12-15 10:49:01 -06:00
|
|
|
EscapeUnicodeState::Backslash => {
|
|
|
|
self.state = EscapeUnicodeState::Type;
|
2014-10-31 18:20:41 -05:00
|
|
|
Some('\\')
|
|
|
|
}
|
2014-12-15 10:49:01 -06:00
|
|
|
EscapeUnicodeState::Type => {
|
|
|
|
self.state = EscapeUnicodeState::LeftBrace;
|
|
|
|
Some('u')
|
2014-10-31 18:20:41 -05:00
|
|
|
}
|
2014-12-15 10:49:01 -06:00
|
|
|
EscapeUnicodeState::LeftBrace => {
|
|
|
|
let mut n = 0u;
|
|
|
|
while (self.c as u32) >> (4 * (n + 1)) != 0 {
|
|
|
|
n += 1;
|
2014-10-31 18:20:41 -05:00
|
|
|
}
|
2014-12-15 10:49:01 -06:00
|
|
|
self.state = EscapeUnicodeState::Value(n);
|
|
|
|
Some('{')
|
|
|
|
}
|
|
|
|
EscapeUnicodeState::Value(offset) => {
|
|
|
|
let v = match ((self.c as i32) >> (offset * 4)) & 0xf {
|
|
|
|
i @ 0 ... 9 => '0' as i32 + i,
|
|
|
|
i => 'a' as i32 + (i - 10)
|
|
|
|
};
|
|
|
|
if offset == 0 {
|
|
|
|
self.state = EscapeUnicodeState::RightBrace;
|
|
|
|
} else {
|
|
|
|
self.state = EscapeUnicodeState::Value(offset - 1);
|
|
|
|
}
|
|
|
|
Some(unsafe { transmute(v) })
|
|
|
|
}
|
|
|
|
EscapeUnicodeState::RightBrace => {
|
|
|
|
self.state = EscapeUnicodeState::Done;
|
|
|
|
Some('}')
|
2014-10-31 18:20:41 -05:00
|
|
|
}
|
2014-12-15 10:49:01 -06:00
|
|
|
EscapeUnicodeState::Done => None,
|
2014-10-31 18:20:41 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// An iterator over the characters that represent a `char`, escaped
|
|
|
|
/// for maximum portability.
|
2014-12-30 04:01:36 -06:00
|
|
|
#[deriving(Clone)]
|
2014-12-15 10:49:01 -06:00
|
|
|
pub struct EscapeDefault {
|
|
|
|
state: EscapeDefaultState
|
2014-10-31 18:20:41 -05:00
|
|
|
}
|
|
|
|
|
2014-12-30 04:01:36 -06:00
|
|
|
#[deriving(Clone)]
|
2014-12-15 10:49:01 -06:00
|
|
|
enum EscapeDefaultState {
|
2014-10-31 18:20:41 -05:00
|
|
|
Backslash(char),
|
|
|
|
Char(char),
|
|
|
|
Done,
|
2014-12-15 10:49:01 -06:00
|
|
|
Unicode(EscapeUnicode),
|
2014-10-31 18:20:41 -05:00
|
|
|
}
|
|
|
|
|
2014-12-29 15:18:41 -06:00
|
|
|
impl Iterator for EscapeDefault {
|
|
|
|
type Item = char;
|
|
|
|
|
2014-10-31 18:20:41 -05:00
|
|
|
fn next(&mut self) -> Option<char> {
|
|
|
|
match self.state {
|
2014-12-15 10:49:01 -06:00
|
|
|
EscapeDefaultState::Backslash(c) => {
|
|
|
|
self.state = EscapeDefaultState::Char(c);
|
2014-10-31 18:20:41 -05:00
|
|
|
Some('\\')
|
|
|
|
}
|
2014-12-15 10:49:01 -06:00
|
|
|
EscapeDefaultState::Char(c) => {
|
|
|
|
self.state = EscapeDefaultState::Done;
|
2014-10-31 18:20:41 -05:00
|
|
|
Some(c)
|
|
|
|
}
|
2014-12-15 10:49:01 -06:00
|
|
|
EscapeDefaultState::Done => None,
|
|
|
|
EscapeDefaultState::Unicode(ref mut iter) => iter.next()
|
2014-10-31 18:20:41 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|