rust/src/libcore/char/methods.rs

1366 lines
41 KiB
Rust
Raw Normal View History

//! impl char {}
2019-04-15 04:23:21 +02:00
use crate::slice;
use crate::str::from_utf8_unchecked_mut;
use crate::unicode::printable::is_printable;
use crate::unicode::tables::{conversions, derived_property, general_category, property};
use super::*;
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 23:04:10 +02:00
2015-03-11 05:13:16 +01:00
#[lang = "char"]
impl char {
/// Checks if a `char` is a digit in the given radix.
///
/// A 'radix' here is sometimes also called a 'base'. A radix of two
/// indicates a binary number, a radix of ten, decimal, and a radix of
2016-01-05 16:40:40 +01:00
/// sixteen, hexadecimal, to give some common values. Arbitrary
2016-11-23 14:49:35 +01:00
/// radices are supported.
2015-03-11 05:13:16 +01:00
///
/// Compared to `is_numeric()`, this function only recognizes the characters
/// `0-9`, `a-z` and `A-Z`.
///
/// 'Digit' is defined to be only the following characters:
2015-03-11 05:13:16 +01:00
///
/// * `0-9`
/// * `a-z`
/// * `A-Z`
///
/// For a more comprehensive understanding of 'digit', see [`is_numeric`][is_numeric].
///
/// [is_numeric]: #method.is_numeric
2015-03-11 05:13:16 +01:00
///
/// # Panics
///
/// Panics if given a radix larger than 36.
2015-03-11 05:13:16 +01:00
///
/// # Examples
///
/// Basic usage:
///
2015-03-11 05:13:16 +01:00
/// ```
2016-03-22 22:09:43 +01:00
/// assert!('1'.is_digit(10));
/// assert!('f'.is_digit(16));
/// assert!(!'f'.is_digit(10));
/// ```
///
/// Passing a large radix, causing a panic:
///
/// ```
/// use std::thread;
///
/// let result = thread::spawn(|| {
/// // this panics
2016-03-22 22:09:43 +01:00
/// '1'.is_digit(37);
/// }).join();
///
/// assert!(result.is_err());
2015-03-11 05:13:16 +01:00
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
2015-10-25 11:19:14 +01:00
pub fn is_digit(self, radix: u32) -> bool {
self.to_digit(radix).is_some()
2015-10-25 11:19:14 +01:00
}
2015-03-11 05:13:16 +01:00
/// Converts a `char` to a digit in the given radix.
///
/// A 'radix' here is sometimes also called a 'base'. A radix of two
/// indicates a binary number, a radix of ten, decimal, and a radix of
2016-01-05 16:40:40 +01:00
/// sixteen, hexadecimal, to give some common values. Arbitrary
2016-11-23 14:49:35 +01:00
/// radices are supported.
///
/// 'Digit' is defined to be only the following characters:
2015-03-11 05:13:16 +01:00
///
/// * `0-9`
/// * `a-z`
/// * `A-Z`
2015-03-11 05:13:16 +01:00
///
/// # Errors
///
/// Returns `None` if the `char` does not refer to a digit in the given radix.
2015-03-11 05:13:16 +01:00
///
/// # Panics
///
/// Panics if given a radix larger than 36.
2015-03-11 05:13:16 +01:00
///
/// # Examples
///
/// Basic usage:
///
/// ```
2016-03-22 22:09:43 +01:00
/// assert_eq!('1'.to_digit(10), Some(1));
/// assert_eq!('f'.to_digit(16), Some(15));
/// ```
///
/// Passing a non-digit results in failure:
///
2015-03-11 05:13:16 +01:00
/// ```
2016-03-22 22:09:43 +01:00
/// assert_eq!('f'.to_digit(10), None);
/// assert_eq!('z'.to_digit(16), None);
/// ```
///
/// Passing a large radix, causing a panic:
///
/// ```
/// use std::thread;
///
/// let result = thread::spawn(|| {
2016-03-22 22:09:43 +01:00
/// '1'.to_digit(37);
/// }).join();
///
/// assert!(result.is_err());
2015-03-11 05:13:16 +01:00
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
2015-10-25 11:19:14 +01:00
pub fn to_digit(self, radix: u32) -> Option<u32> {
assert!(radix <= 36, "to_digit: radix is too high (maximum 36)");
2018-11-14 11:26:00 +01:00
// the code is split up here to improve execution speed for cases where
// the `radix` is constant and 10 or smaller
let val = if radix <= 10 {
core/char: Speed up `to_digit()` for `radix <= 10` ### Before ``` # Run 1 test char::methods::bench_to_digit_radix_10 ... bench: 16,265 ns/iter (+/- 1,774) test char::methods::bench_to_digit_radix_16 ... bench: 13,938 ns/iter (+/- 2,479) test char::methods::bench_to_digit_radix_2 ... bench: 13,090 ns/iter (+/- 524) test char::methods::bench_to_digit_radix_36 ... bench: 14,236 ns/iter (+/- 1,949) # Run 2 test char::methods::bench_to_digit_radix_10 ... bench: 16,176 ns/iter (+/- 1,589) test char::methods::bench_to_digit_radix_16 ... bench: 13,896 ns/iter (+/- 3,140) test char::methods::bench_to_digit_radix_2 ... bench: 13,158 ns/iter (+/- 1,112) test char::methods::bench_to_digit_radix_36 ... bench: 14,206 ns/iter (+/- 1,312) # Run 3 test char::methods::bench_to_digit_radix_10 ... bench: 16,221 ns/iter (+/- 2,423) test char::methods::bench_to_digit_radix_16 ... bench: 14,361 ns/iter (+/- 3,926) test char::methods::bench_to_digit_radix_2 ... bench: 13,097 ns/iter (+/- 671) test char::methods::bench_to_digit_radix_36 ... bench: 14,388 ns/iter (+/- 1,068) ``` ### After ``` # Run 1 test char::methods::bench_to_digit_radix_10 ... bench: 11,521 ns/iter (+/- 552) test char::methods::bench_to_digit_radix_16 ... bench: 12,926 ns/iter (+/- 684) test char::methods::bench_to_digit_radix_2 ... bench: 11,266 ns/iter (+/- 1,085) test char::methods::bench_to_digit_radix_36 ... bench: 14,213 ns/iter (+/- 614) # Run 2 test char::methods::bench_to_digit_radix_10 ... bench: 11,424 ns/iter (+/- 1,042) test char::methods::bench_to_digit_radix_16 ... bench: 12,854 ns/iter (+/- 1,193) test char::methods::bench_to_digit_radix_2 ... bench: 11,193 ns/iter (+/- 716) test char::methods::bench_to_digit_radix_36 ... bench: 14,249 ns/iter (+/- 3,514) # Run 3 test char::methods::bench_to_digit_radix_10 ... bench: 11,469 ns/iter (+/- 685) test char::methods::bench_to_digit_radix_16 ... bench: 12,852 ns/iter (+/- 568) test char::methods::bench_to_digit_radix_2 ... bench: 11,275 ns/iter (+/- 1,356) test char::methods::bench_to_digit_radix_36 ... bench: 14,188 ns/iter (+/- 1,501) ```
2018-11-13 18:05:46 +01:00
match self {
'0' ..= '9' => self as u32 - '0' as u32,
_ => return None,
}
} else {
match self {
'0'..='9' => self as u32 - '0' as u32,
'a'..='z' => self as u32 - 'a' as u32 + 10,
'A'..='Z' => self as u32 - 'A' as u32 + 10,
_ => return None,
}
};
core/char: Speed up `to_digit()` for `radix <= 10` ### Before ``` # Run 1 test char::methods::bench_to_digit_radix_10 ... bench: 16,265 ns/iter (+/- 1,774) test char::methods::bench_to_digit_radix_16 ... bench: 13,938 ns/iter (+/- 2,479) test char::methods::bench_to_digit_radix_2 ... bench: 13,090 ns/iter (+/- 524) test char::methods::bench_to_digit_radix_36 ... bench: 14,236 ns/iter (+/- 1,949) # Run 2 test char::methods::bench_to_digit_radix_10 ... bench: 16,176 ns/iter (+/- 1,589) test char::methods::bench_to_digit_radix_16 ... bench: 13,896 ns/iter (+/- 3,140) test char::methods::bench_to_digit_radix_2 ... bench: 13,158 ns/iter (+/- 1,112) test char::methods::bench_to_digit_radix_36 ... bench: 14,206 ns/iter (+/- 1,312) # Run 3 test char::methods::bench_to_digit_radix_10 ... bench: 16,221 ns/iter (+/- 2,423) test char::methods::bench_to_digit_radix_16 ... bench: 14,361 ns/iter (+/- 3,926) test char::methods::bench_to_digit_radix_2 ... bench: 13,097 ns/iter (+/- 671) test char::methods::bench_to_digit_radix_36 ... bench: 14,388 ns/iter (+/- 1,068) ``` ### After ``` # Run 1 test char::methods::bench_to_digit_radix_10 ... bench: 11,521 ns/iter (+/- 552) test char::methods::bench_to_digit_radix_16 ... bench: 12,926 ns/iter (+/- 684) test char::methods::bench_to_digit_radix_2 ... bench: 11,266 ns/iter (+/- 1,085) test char::methods::bench_to_digit_radix_36 ... bench: 14,213 ns/iter (+/- 614) # Run 2 test char::methods::bench_to_digit_radix_10 ... bench: 11,424 ns/iter (+/- 1,042) test char::methods::bench_to_digit_radix_16 ... bench: 12,854 ns/iter (+/- 1,193) test char::methods::bench_to_digit_radix_2 ... bench: 11,193 ns/iter (+/- 716) test char::methods::bench_to_digit_radix_36 ... bench: 14,249 ns/iter (+/- 3,514) # Run 3 test char::methods::bench_to_digit_radix_10 ... bench: 11,469 ns/iter (+/- 685) test char::methods::bench_to_digit_radix_16 ... bench: 12,852 ns/iter (+/- 568) test char::methods::bench_to_digit_radix_2 ... bench: 11,275 ns/iter (+/- 1,356) test char::methods::bench_to_digit_radix_36 ... bench: 14,188 ns/iter (+/- 1,501) ```
2018-11-13 18:05:46 +01:00
if val < radix { Some(val) }
else { None }
2015-10-25 11:19:14 +01:00
}
2015-03-11 05:13:16 +01:00
/// Returns an iterator that yields the hexadecimal Unicode escape of a
/// character as `char`s.
2015-03-11 05:13:16 +01:00
///
/// This will escape characters with the Rust syntax of the form
/// `\u{NNNNNN}` where `NNNNNN` is a hexadecimal representation.
2015-03-11 05:13:16 +01:00
///
/// # Examples
///
/// As an iterator:
///
2015-03-11 05:13:16 +01:00
/// ```
/// for c in '❤'.escape_unicode() {
/// print!("{}", c);
2015-03-11 05:13:16 +01:00
/// }
/// println!();
2015-03-11 05:13:16 +01:00
/// ```
///
/// Using `println!` directly:
2015-03-11 05:13:16 +01:00
///
/// ```
/// println!("{}", '❤'.escape_unicode());
2015-03-11 05:13:16 +01:00
/// ```
///
/// Both are equivalent to:
2015-03-11 05:13:16 +01:00
///
/// ```
/// println!("\\u{{2764}}");
/// ```
2015-03-11 05:13:16 +01:00
///
/// Using `to_string`:
///
/// ```
/// assert_eq!('❤'.escape_unicode().to_string(), "\\u{2764}");
2015-03-11 05:13:16 +01:00
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
2015-10-25 11:19:14 +01:00
pub fn escape_unicode(self) -> EscapeUnicode {
let c = self as u32;
// or-ing 1 ensures that for c==0 the code computes that one
// digit should be printed and (which is the same) avoids the
// (31 - 32) underflow
let msb = 31 - (c | 1).leading_zeros();
// the index of the most significant hex digit
let ms_hex_digit = msb / 4;
EscapeUnicode {
c: self,
state: EscapeUnicodeState::Backslash,
hex_digit_idx: ms_hex_digit as usize,
}
2015-10-25 11:19:14 +01:00
}
2015-03-11 05:13:16 +01:00
/// An extended version of `escape_debug` that optionally permits escaping
/// Extended Grapheme codepoints. This allows us to format characters like
/// nonspacing marks better when they're at the start of a string.
#[inline]
pub(crate) fn escape_debug_ext(self, escape_grapheme_extended: bool) -> EscapeDebug {
let init_state = match self {
'\t' => EscapeDefaultState::Backslash('t'),
'\r' => EscapeDefaultState::Backslash('r'),
'\n' => EscapeDefaultState::Backslash('n'),
'\\' | '\'' | '"' => EscapeDefaultState::Backslash(self),
_ if escape_grapheme_extended && self.is_grapheme_extended() => {
EscapeDefaultState::Unicode(self.escape_unicode())
}
_ if is_printable(self) => EscapeDefaultState::Char(self),
_ => EscapeDefaultState::Unicode(self.escape_unicode()),
};
EscapeDebug(EscapeDefault { state: init_state })
}
/// Returns an iterator that yields the literal escape code of a character
/// as `char`s.
///
/// This will escape the characters similar to the `Debug` implementations
/// of `str` or `char`.
///
/// # Examples
///
/// As an iterator:
///
/// ```
/// for c in '\n'.escape_debug() {
/// print!("{}", c);
/// }
/// println!();
/// ```
///
/// Using `println!` directly:
///
/// ```
/// println!("{}", '\n'.escape_debug());
/// ```
///
/// Both are equivalent to:
///
/// ```
/// println!("\\n");
/// ```
///
/// Using `to_string`:
///
/// ```
/// assert_eq!('\n'.escape_debug().to_string(), "\\n");
/// ```
#[stable(feature = "char_escape_debug", since = "1.20.0")]
#[inline]
pub fn escape_debug(self) -> EscapeDebug {
self.escape_debug_ext(true)
}
/// Returns an iterator that yields the literal escape code of a character
/// as `char`s.
2015-03-11 05:13:16 +01: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 is escaped as `\t`.
/// * Carriage return is escaped as `\r`.
/// * Line feed is escaped as `\n`.
/// * Single quote is escaped as `\'`.
/// * Double quote is escaped as `\"`.
/// * Backslash is escaped as `\\`.
/// * Any character in the 'printable ASCII' range `0x20` .. `0x7e`
/// inclusive is not escaped.
/// * All other characters are given hexadecimal Unicode escapes; see
/// [`escape_unicode`][escape_unicode].
///
/// [escape_unicode]: #method.escape_unicode
2015-03-11 05:13:16 +01:00
///
/// # Examples
///
/// As an iterator:
///
2015-03-11 05:13:16 +01:00
/// ```
/// for c in '"'.escape_default() {
/// print!("{}", c);
2015-03-11 05:13:16 +01:00
/// }
/// println!();
2015-03-11 05:13:16 +01:00
/// ```
///
/// Using `println!` directly:
2015-03-11 05:13:16 +01:00
///
/// ```
/// println!("{}", '"'.escape_default());
/// ```
///
2015-03-11 05:13:16 +01:00
///
/// Both are equivalent to:
2015-03-11 05:13:16 +01:00
///
/// ```
/// println!("\\\"");
/// ```
///
/// Using `to_string`:
2015-03-11 05:13:16 +01:00
///
/// ```
/// assert_eq!('"'.escape_default().to_string(), "\\\"");
2015-03-11 05:13:16 +01:00
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
2015-10-25 11:19:14 +01:00
pub fn escape_default(self) -> EscapeDefault {
let init_state = match self {
'\t' => EscapeDefaultState::Backslash('t'),
'\r' => EscapeDefaultState::Backslash('r'),
'\n' => EscapeDefaultState::Backslash('n'),
'\\' | '\'' | '"' => EscapeDefaultState::Backslash(self),
'\x20' ..= '\x7e' => EscapeDefaultState::Char(self),
_ => EscapeDefaultState::Unicode(self.escape_unicode())
};
EscapeDefault { state: init_state }
2015-10-25 11:19:14 +01:00
}
2015-03-11 05:13:16 +01:00
/// Returns the number of bytes this `char` would need if encoded in UTF-8.
///
/// That number of bytes is always between 1 and 4, inclusive.
2015-03-11 05:13:16 +01:00
///
/// # Examples
///
/// Basic usage:
///
2015-03-11 05:13:16 +01:00
/// ```
/// let len = 'A'.len_utf8();
/// assert_eq!(len, 1);
///
/// let len = 'ß'.len_utf8();
/// assert_eq!(len, 2);
2015-03-11 05:13:16 +01:00
///
/// let len = ''.len_utf8();
/// assert_eq!(len, 3);
///
/// let len = '💣'.len_utf8();
/// assert_eq!(len, 4);
/// ```
///
/// The `&str` type guarantees that its contents are UTF-8, and so we can compare the length it
/// would take if each code point was represented as a `char` vs in the `&str` itself:
///
/// ```
/// // as chars
/// let eastern = '東';
/// let capital = '京';
///
/// // both can be represented as three bytes
/// assert_eq!(3, eastern.len_utf8());
2019-06-29 19:46:45 +02:00
/// assert_eq!(3, capital.len_utf8());
///
/// // as a &str, these two are encoded in UTF-8
/// let tokyo = "東京";
///
2019-06-29 19:46:45 +02:00
/// let len = eastern.len_utf8() + capital.len_utf8();
///
/// // we can see that they take six bytes total...
/// assert_eq!(6, tokyo.len());
///
/// // ... just like the &str
/// assert_eq!(len, tokyo.len());
2015-03-11 05:13:16 +01:00
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
2015-10-25 11:19:14 +01:00
pub fn len_utf8(self) -> usize {
let code = self as u32;
if code < MAX_ONE_B {
1
} else if code < MAX_TWO_B {
2
} else if code < MAX_THREE_B {
3
} else {
4
}
2015-10-25 11:19:14 +01:00
}
2015-03-11 05:13:16 +01:00
/// Returns the number of 16-bit code units this `char` would need if
2015-03-11 05:13:16 +01:00
/// encoded in UTF-16.
///
/// See the documentation for [`len_utf8`] for more explanation of this
2015-12-09 21:58:49 +01:00
/// concept. This function is a mirror, but for UTF-16 instead of UTF-8.
///
/// [`len_utf8`]: #method.len_utf8
///
2015-03-11 05:13:16 +01:00
/// # Examples
///
/// Basic usage:
///
2015-03-11 05:13:16 +01:00
/// ```
/// let n = 'ß'.len_utf16();
/// assert_eq!(n, 1);
///
/// let len = '💣'.len_utf16();
/// assert_eq!(len, 2);
2015-03-11 05:13:16 +01:00
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
2015-10-25 11:19:14 +01:00
pub fn len_utf16(self) -> usize {
let ch = self as u32;
if (ch & 0xFFFF) == ch { 1 } else { 2 }
2015-10-25 11:19:14 +01:00
}
2015-03-11 05:13:16 +01:00
/// Encodes this character as UTF-8 into the provided byte buffer,
/// and then returns the subslice of the buffer that contains the encoded character.
2015-03-11 05:13:16 +01:00
///
/// # Panics
///
/// Panics if the buffer is not large enough.
/// A buffer of length four is large enough to encode any `char`.
2015-03-11 05:13:16 +01:00
///
/// # Examples
///
/// In both of these examples, 'ß' takes two bytes to encode.
///
2015-03-11 05:13:16 +01:00
/// ```
/// let mut b = [0; 2];
2015-03-11 05:13:16 +01:00
///
/// let result = 'ß'.encode_utf8(&mut b);
///
/// assert_eq!(result, "ß");
///
/// assert_eq!(result.len(), 2);
/// ```
///
/// A buffer that's too small:
///
/// ```
/// use std::thread;
///
/// let result = thread::spawn(|| {
/// let mut b = [0; 1];
///
/// // this panics
/// 'ß'.encode_utf8(&mut b);
/// }).join();
///
/// assert!(result.is_err());
2015-03-11 05:13:16 +01:00
/// ```
#[stable(feature = "unicode_encode_char", since = "1.15.0")]
#[inline]
pub fn encode_utf8(self, dst: &mut [u8]) -> &mut str {
let code = self as u32;
unsafe {
let len =
if code < MAX_ONE_B && !dst.is_empty() {
*dst.get_unchecked_mut(0) = code as u8;
1
} else if code < MAX_TWO_B && dst.len() >= 2 {
*dst.get_unchecked_mut(0) = (code >> 6 & 0x1F) as u8 | TAG_TWO_B;
*dst.get_unchecked_mut(1) = (code & 0x3F) as u8 | TAG_CONT;
2
} else if code < MAX_THREE_B && dst.len() >= 3 {
*dst.get_unchecked_mut(0) = (code >> 12 & 0x0F) as u8 | TAG_THREE_B;
*dst.get_unchecked_mut(1) = (code >> 6 & 0x3F) as u8 | TAG_CONT;
*dst.get_unchecked_mut(2) = (code & 0x3F) as u8 | TAG_CONT;
3
} else if dst.len() >= 4 {
*dst.get_unchecked_mut(0) = (code >> 18 & 0x07) as u8 | TAG_FOUR_B;
*dst.get_unchecked_mut(1) = (code >> 12 & 0x3F) as u8 | TAG_CONT;
*dst.get_unchecked_mut(2) = (code >> 6 & 0x3F) as u8 | TAG_CONT;
*dst.get_unchecked_mut(3) = (code & 0x3F) as u8 | TAG_CONT;
4
} else {
panic!("encode_utf8: need {} bytes to encode U+{:X}, but the buffer has {}",
from_u32_unchecked(code).len_utf8(),
code,
dst.len())
};
from_utf8_unchecked_mut(dst.get_unchecked_mut(..len))
}
}
2015-03-11 05:13:16 +01:00
/// Encodes this character as UTF-16 into the provided `u16` buffer,
/// and then returns the subslice of the buffer that contains the encoded character.
2015-03-11 05:13:16 +01:00
///
/// # Panics
///
/// Panics if the buffer is not large enough.
/// A buffer of length 2 is large enough to encode any `char`.
2015-03-11 05:13:16 +01:00
///
/// # Examples
///
/// In both of these examples, '𝕊' takes two `u16`s to encode.
///
2015-03-11 05:13:16 +01:00
/// ```
/// let mut b = [0; 2];
2015-03-11 05:13:16 +01:00
///
/// let result = '𝕊'.encode_utf16(&mut b);
///
/// assert_eq!(result.len(), 2);
/// ```
///
/// A buffer that's too small:
///
/// ```
/// use std::thread;
///
/// let result = thread::spawn(|| {
/// let mut b = [0; 1];
///
/// // this panics
/// '𝕊'.encode_utf16(&mut b);
/// }).join();
///
/// assert!(result.is_err());
2015-03-11 05:13:16 +01:00
/// ```
#[stable(feature = "unicode_encode_char", since = "1.15.0")]
#[inline]
pub fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] {
let mut code = self as u32;
unsafe {
if (code & 0xFFFF) == code && !dst.is_empty() {
// The BMP falls through (assuming non-surrogate, as it should)
*dst.get_unchecked_mut(0) = code as u16;
slice::from_raw_parts_mut(dst.as_mut_ptr(), 1)
} else if dst.len() >= 2 {
// Supplementary planes break into surrogates.
code -= 0x1_0000;
*dst.get_unchecked_mut(0) = 0xD800 | ((code >> 10) as u16);
*dst.get_unchecked_mut(1) = 0xDC00 | ((code as u16) & 0x3FF);
slice::from_raw_parts_mut(dst.as_mut_ptr(), 2)
} else {
panic!("encode_utf16: need {} units to encode U+{:X}, but the buffer has {}",
from_u32_unchecked(code).len_utf16(),
code,
dst.len())
}
}
}
2015-03-11 05:13:16 +01:00
2019-02-09 23:16:58 +01:00
/// Returns `true` if this `char` is an alphabetic code point, and false if not.
///
/// # Examples
///
/// Basic usage:
///
/// ```
2016-03-22 22:09:43 +01:00
/// assert!('a'.is_alphabetic());
/// assert!('京'.is_alphabetic());
///
/// let c = '💝';
/// // love is many things, but it is not alphabetic
/// assert!(!c.is_alphabetic());
/// ```
2015-03-11 05:13:16 +01:00
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
2015-03-11 05:13:16 +01:00
pub fn is_alphabetic(self) -> bool {
match self {
'a'..='z' | 'A'..='Z' => true,
2015-03-11 05:13:16 +01:00
c if c > '\x7f' => derived_property::Alphabetic(c),
2015-10-25 11:19:14 +01:00
_ => false,
2015-03-11 05:13:16 +01:00
}
}
2019-02-09 23:16:58 +01:00
/// Returns `true` if this `char` is lowercase.
2015-03-11 05:13:16 +01:00
///
/// 'Lowercase' is defined according to the terms of the Unicode Derived Core
2015-03-11 05:13:16 +01:00
/// Property `Lowercase`.
///
/// # Examples
///
/// Basic usage:
///
/// ```
2016-03-22 22:09:43 +01:00
/// assert!('a'.is_lowercase());
/// assert!('δ'.is_lowercase());
/// assert!(!'A'.is_lowercase());
/// assert!(!'Δ'.is_lowercase());
///
/// // The various Chinese scripts do not have case, and so:
2016-03-22 22:09:43 +01:00
/// assert!(!'中'.is_lowercase());
/// ```
2015-03-11 05:13:16 +01:00
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
2015-03-11 05:13:16 +01:00
pub fn is_lowercase(self) -> bool {
match self {
'a'..='z' => true,
2015-03-11 05:13:16 +01:00
c if c > '\x7f' => derived_property::Lowercase(c),
2015-10-25 11:19:14 +01:00
_ => false,
2015-03-11 05:13:16 +01:00
}
}
2019-02-09 23:16:58 +01:00
/// Returns `true` if this `char` is uppercase.
2015-03-11 05:13:16 +01:00
///
/// 'Uppercase' is defined according to the terms of the Unicode Derived Core
2015-03-11 05:13:16 +01:00
/// Property `Uppercase`.
///
/// # Examples
///
/// Basic usage:
///
/// ```
2016-03-22 22:09:43 +01:00
/// assert!(!'a'.is_uppercase());
/// assert!(!'δ'.is_uppercase());
/// assert!('A'.is_uppercase());
/// assert!('Δ'.is_uppercase());
///
/// // The various Chinese scripts do not have case, and so:
2016-03-22 22:09:43 +01:00
/// assert!(!'中'.is_uppercase());
/// ```
2015-03-11 05:13:16 +01:00
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
2015-03-11 05:13:16 +01:00
pub fn is_uppercase(self) -> bool {
match self {
'A'..='Z' => true,
2015-03-11 05:13:16 +01:00
c if c > '\x7f' => derived_property::Uppercase(c),
2015-10-25 11:19:14 +01:00
_ => false,
2015-03-11 05:13:16 +01:00
}
}
2019-02-09 23:16:58 +01:00
/// Returns `true` if this `char` is whitespace.
2015-03-11 05:13:16 +01:00
///
/// 'Whitespace' is defined according to the terms of the Unicode Derived Core
/// Property `White_Space`.
///
/// # Examples
///
/// Basic usage:
///
/// ```
2016-03-22 22:09:43 +01:00
/// assert!(' '.is_whitespace());
///
/// // a non-breaking space
2016-03-22 22:09:43 +01:00
/// assert!('\u{A0}'.is_whitespace());
///
2016-03-22 22:09:43 +01:00
/// assert!(!'越'.is_whitespace());
/// ```
2015-03-11 05:13:16 +01:00
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
2015-03-11 05:13:16 +01:00
pub fn is_whitespace(self) -> bool {
match self {
' ' | '\x09'..='\x0d' => true,
2015-03-11 05:13:16 +01:00
c if c > '\x7f' => property::White_Space(c),
2015-10-25 11:19:14 +01:00
_ => false,
2015-03-11 05:13:16 +01:00
}
}
2019-02-09 23:16:58 +01:00
/// Returns `true` if this `char` is alphanumeric.
2015-03-11 05:13:16 +01:00
///
/// 'Alphanumeric'-ness is defined in terms of the Unicode General Categories
2019-07-25 17:56:58 +02:00
/// `Nd`, `Nl`, `No` and the Derived Core Property `Alphabetic`.
///
/// # Examples
///
/// Basic usage:
///
/// ```
2016-03-22 22:09:43 +01:00
/// assert!('٣'.is_alphanumeric());
/// assert!('7'.is_alphanumeric());
/// assert!('৬'.is_alphanumeric());
2018-06-17 18:58:01 +02:00
/// assert!('¾'.is_alphanumeric());
/// assert!('①'.is_alphanumeric());
2016-03-22 22:09:43 +01:00
/// assert!('K'.is_alphanumeric());
/// assert!('و'.is_alphanumeric());
/// assert!('藏'.is_alphanumeric());
/// ```
2015-03-11 05:13:16 +01:00
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
2015-03-11 05:13:16 +01:00
pub fn is_alphanumeric(self) -> bool {
self.is_alphabetic() || self.is_numeric()
}
2019-02-09 23:16:58 +01:00
/// Returns `true` if this `char` is a control code point.
2015-03-11 05:13:16 +01:00
///
/// 'Control code point' is defined in terms of the Unicode General
2015-03-11 05:13:16 +01:00
/// Category `Cc`.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// // U+009C, STRING TERMINATOR
2016-03-22 22:09:43 +01:00
/// assert!('œ'.is_control());
/// assert!(!'q'.is_control());
/// ```
2015-03-11 05:13:16 +01:00
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
2015-10-25 11:19:14 +01:00
pub fn is_control(self) -> bool {
general_category::Cc(self)
}
2015-03-11 05:13:16 +01:00
2019-02-09 23:16:58 +01:00
/// Returns `true` if this `char` is an extended grapheme character.
///
2018-05-17 00:19:58 +02:00
/// 'Extended grapheme character' is defined in terms of the Unicode Shaping and Rendering
/// Category `Grapheme_Extend`.
#[inline]
2018-05-17 00:19:58 +02:00
pub(crate) fn is_grapheme_extended(self) -> bool {
derived_property::Grapheme_Extend(self)
}
2019-02-09 23:16:58 +01:00
/// Returns `true` if this `char` is numeric.
///
/// 'Numeric'-ness is defined in terms of the Unicode General Categories
2019-07-25 17:56:58 +02:00
/// `Nd`, `Nl`, `No`.
///
/// # Examples
///
/// Basic usage:
///
/// ```
2016-03-22 22:09:43 +01:00
/// assert!('٣'.is_numeric());
/// assert!('7'.is_numeric());
/// assert!('৬'.is_numeric());
2018-06-17 18:58:01 +02:00
/// assert!('¾'.is_numeric());
/// assert!('①'.is_numeric());
2016-03-22 22:09:43 +01:00
/// assert!(!'K'.is_numeric());
/// assert!(!'و'.is_numeric());
/// assert!(!'藏'.is_numeric());
/// ```
2015-03-11 05:13:16 +01:00
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
2015-03-11 05:13:16 +01:00
pub fn is_numeric(self) -> bool {
match self {
'0'..='9' => true,
2015-03-11 05:13:16 +01:00
c if c > '\x7f' => general_category::N(c),
2015-10-25 11:19:14 +01:00
_ => false,
2015-03-11 05:13:16 +01:00
}
}
/// Returns an iterator that yields the lowercase equivalent of a `char`
/// as one or more `char`s.
2015-03-11 05:13:16 +01:00
///
/// If a character does not have a lowercase equivalent, the same character
/// will be returned back by the iterator.
2015-03-11 05:13:16 +01:00
///
/// This performs complex unconditional mappings with no tailoring: it maps
/// one Unicode character to its lowercase equivalent according to the
/// [Unicode database] and the additional complex mappings
/// [`SpecialCasing.txt`]. Conditional mappings (based on context or
/// language) are not considered here.
2015-03-11 05:13:16 +01:00
///
/// For a full reference, see [here][reference].
///
/// [Unicode database]: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
///
/// [`SpecialCasing.txt`]: ftp://ftp.unicode.org/Public/UNIDATA/SpecialCasing.txt
///
/// [reference]: http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992
///
/// # Examples
///
/// As an iterator:
///
/// ```
/// for c in 'İ'.to_lowercase() {
/// print!("{}", c);
/// }
/// println!();
/// ```
///
/// Using `println!` directly:
///
/// ```
/// println!("{}", 'İ'.to_lowercase());
/// ```
///
/// Both are equivalent to:
///
/// ```
/// println!("i\u{307}");
/// ```
///
/// Using `to_string`:
///
/// ```
/// assert_eq!('C'.to_lowercase().to_string(), "c");
///
/// // Sometimes the result is more than one character:
/// assert_eq!('İ'.to_lowercase().to_string(), "i\u{307}");
///
/// // Characters that do not have both uppercase and lowercase
/// // convert into themselves.
/// assert_eq!('山'.to_lowercase().to_string(), "山");
/// ```
2015-03-11 05:13:16 +01:00
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
2015-03-11 05:13:16 +01:00
pub fn to_lowercase(self) -> ToLowercase {
ToLowercase(CaseMappingIter::new(conversions::to_lower(self)))
2015-03-11 05:13:16 +01:00
}
/// Returns an iterator that yields the uppercase equivalent of a `char`
/// as one or more `char`s.
2015-03-11 05:13:16 +01:00
///
/// If a character does not have an uppercase equivalent, the same character
/// will be returned back by the iterator.
2015-03-11 05:13:16 +01:00
///
/// This performs complex unconditional mappings with no tailoring: it maps
/// one Unicode character to its uppercase equivalent according to the
/// [Unicode database] and the additional complex mappings
/// [`SpecialCasing.txt`]. Conditional mappings (based on context or
/// language) are not considered here.
2015-03-11 05:13:16 +01:00
///
/// For a full reference, see [here][reference].
2015-03-11 05:13:16 +01:00
///
/// [Unicode database]: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
2015-03-11 05:13:16 +01:00
///
2015-05-19 19:36:10 +02:00
/// [`SpecialCasing.txt`]: ftp://ftp.unicode.org/Public/UNIDATA/SpecialCasing.txt
2015-03-11 05:13:16 +01:00
///
/// [reference]: http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992
///
/// # Examples
///
/// As an iterator:
///
/// ```
/// for c in 'ß'.to_uppercase() {
/// print!("{}", c);
/// }
/// println!();
/// ```
///
/// Using `println!` directly:
///
/// ```
/// println!("{}", 'ß'.to_uppercase());
/// ```
///
/// Both are equivalent to:
///
/// ```
/// println!("SS");
/// ```
///
/// Using `to_string`:
///
/// ```
/// assert_eq!('c'.to_uppercase().to_string(), "C");
///
/// // Sometimes the result is more than one character:
/// assert_eq!('ß'.to_uppercase().to_string(), "SS");
///
/// // Characters that do not have both uppercase and lowercase
/// // convert into themselves.
/// assert_eq!('山'.to_uppercase().to_string(), "山");
/// ```
///
/// # Note on locale
///
/// In Turkish, the equivalent of 'i' in Latin has five forms instead of two:
///
/// * 'Dotless': I / ı, sometimes written ï
/// * 'Dotted': İ / i
///
/// Note that the lowercase dotted 'i' is the same as the Latin. Therefore:
///
/// ```
/// let upper_i = 'i'.to_uppercase().to_string();
/// ```
///
/// The value of `upper_i` here relies on the language of the text: if we're
/// in `en-US`, it should be `"I"`, but if we're in `tr_TR`, it should
/// be `"İ"`. `to_uppercase()` does not take this into account, and so:
///
/// ```
/// let upper_i = 'i'.to_uppercase().to_string();
///
/// assert_eq!(upper_i, "I");
/// ```
///
/// holds across languages.
2015-03-11 05:13:16 +01:00
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
2015-03-11 05:13:16 +01:00
pub fn to_uppercase(self) -> ToUppercase {
ToUppercase(CaseMappingIter::new(conversions::to_upper(self)))
2015-03-11 05:13:16 +01:00
}
/// Checks if the value is within the ASCII range.
///
/// # Examples
///
/// ```
/// let ascii = 'a';
/// let non_ascii = '❤';
///
/// assert!(ascii.is_ascii());
/// assert!(!non_ascii.is_ascii());
/// ```
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
2018-10-23 02:04:14 +02:00
pub const fn is_ascii(&self) -> bool {
*self as u32 <= 0x7F
}
/// Makes a copy of the value in its ASCII upper case equivalent.
///
/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
/// but non-ASCII letters are unchanged.
///
/// To uppercase the value in-place, use [`make_ascii_uppercase`].
///
/// To uppercase ASCII characters in addition to non-ASCII characters, use
/// [`to_uppercase`].
///
/// # Examples
///
/// ```
/// let ascii = 'a';
/// let non_ascii = '❤';
///
/// assert_eq!('A', ascii.to_ascii_uppercase());
/// assert_eq!('❤', non_ascii.to_ascii_uppercase());
/// ```
///
/// [`make_ascii_uppercase`]: #method.make_ascii_uppercase
/// [`to_uppercase`]: #method.to_uppercase
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
pub fn to_ascii_uppercase(&self) -> char {
if self.is_ascii() {
(*self as u8).to_ascii_uppercase() as char
} else {
*self
}
}
/// Makes a copy of the value in its ASCII lower case equivalent.
///
/// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
/// but non-ASCII letters are unchanged.
///
/// To lowercase the value in-place, use [`make_ascii_lowercase`].
///
/// To lowercase ASCII characters in addition to non-ASCII characters, use
/// [`to_lowercase`].
///
/// # Examples
///
/// ```
/// let ascii = 'A';
/// let non_ascii = '❤';
///
/// assert_eq!('a', ascii.to_ascii_lowercase());
/// assert_eq!('❤', non_ascii.to_ascii_lowercase());
/// ```
///
/// [`make_ascii_lowercase`]: #method.make_ascii_lowercase
/// [`to_lowercase`]: #method.to_lowercase
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
pub fn to_ascii_lowercase(&self) -> char {
if self.is_ascii() {
(*self as u8).to_ascii_lowercase() as char
} else {
*self
}
}
/// Checks that two values are an ASCII case-insensitive match.
///
/// Equivalent to `to_ascii_lowercase(a) == to_ascii_lowercase(b)`.
///
/// # Examples
///
/// ```
/// let upper_a = 'A';
/// let lower_a = 'a';
/// let lower_z = 'z';
///
/// assert!(upper_a.eq_ignore_ascii_case(&lower_a));
/// assert!(upper_a.eq_ignore_ascii_case(&upper_a));
/// assert!(!upper_a.eq_ignore_ascii_case(&lower_z));
/// ```
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
pub fn eq_ignore_ascii_case(&self, other: &char) -> bool {
self.to_ascii_lowercase() == other.to_ascii_lowercase()
}
/// Converts this type to its ASCII upper case equivalent in-place.
///
/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
/// but non-ASCII letters are unchanged.
///
/// To return a new uppercased value without modifying the existing one, use
/// [`to_ascii_uppercase`].
///
/// # Examples
///
/// ```
/// let mut ascii = 'a';
///
/// ascii.make_ascii_uppercase();
///
/// assert_eq!('A', ascii);
/// ```
///
/// [`to_ascii_uppercase`]: #method.to_ascii_uppercase
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
pub fn make_ascii_uppercase(&mut self) {
*self = self.to_ascii_uppercase();
}
/// Converts this type to its ASCII lower case equivalent in-place.
///
/// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
/// but non-ASCII letters are unchanged.
///
/// To return a new lowercased value without modifying the existing one, use
/// [`to_ascii_lowercase`].
///
/// # Examples
///
/// ```
/// let mut ascii = 'A';
///
/// ascii.make_ascii_lowercase();
///
/// assert_eq!('a', ascii);
/// ```
///
/// [`to_ascii_lowercase`]: #method.to_ascii_lowercase
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
pub fn make_ascii_lowercase(&mut self) {
*self = self.to_ascii_lowercase();
}
/// Checks if the value is an ASCII alphabetic character:
///
2019-06-14 19:24:38 +02:00
/// - U+0041 'A' ..= U+005A 'Z', or
/// - U+0061 'a' ..= U+007A 'z'.
///
/// # Examples
///
/// ```
/// let uppercase_a = 'A';
/// let uppercase_g = 'G';
/// let a = 'a';
/// let g = 'g';
/// let zero = '0';
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
///
/// assert!(uppercase_a.is_ascii_alphabetic());
/// assert!(uppercase_g.is_ascii_alphabetic());
/// assert!(a.is_ascii_alphabetic());
/// assert!(g.is_ascii_alphabetic());
/// assert!(!zero.is_ascii_alphabetic());
/// assert!(!percent.is_ascii_alphabetic());
/// assert!(!space.is_ascii_alphabetic());
/// assert!(!lf.is_ascii_alphabetic());
/// assert!(!esc.is_ascii_alphabetic());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[inline]
pub fn is_ascii_alphabetic(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_alphabetic()
}
/// Checks if the value is an ASCII uppercase character:
2019-06-14 19:24:38 +02:00
/// U+0041 'A' ..= U+005A 'Z'.
///
/// # Examples
///
/// ```
/// let uppercase_a = 'A';
/// let uppercase_g = 'G';
/// let a = 'a';
/// let g = 'g';
/// let zero = '0';
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
///
/// assert!(uppercase_a.is_ascii_uppercase());
/// assert!(uppercase_g.is_ascii_uppercase());
/// assert!(!a.is_ascii_uppercase());
/// assert!(!g.is_ascii_uppercase());
/// assert!(!zero.is_ascii_uppercase());
/// assert!(!percent.is_ascii_uppercase());
/// assert!(!space.is_ascii_uppercase());
/// assert!(!lf.is_ascii_uppercase());
/// assert!(!esc.is_ascii_uppercase());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[inline]
pub fn is_ascii_uppercase(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_uppercase()
}
/// Checks if the value is an ASCII lowercase character:
2019-06-14 19:24:38 +02:00
/// U+0061 'a' ..= U+007A 'z'.
///
/// # Examples
///
/// ```
/// let uppercase_a = 'A';
/// let uppercase_g = 'G';
/// let a = 'a';
/// let g = 'g';
/// let zero = '0';
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
///
/// assert!(!uppercase_a.is_ascii_lowercase());
/// assert!(!uppercase_g.is_ascii_lowercase());
/// assert!(a.is_ascii_lowercase());
/// assert!(g.is_ascii_lowercase());
/// assert!(!zero.is_ascii_lowercase());
/// assert!(!percent.is_ascii_lowercase());
/// assert!(!space.is_ascii_lowercase());
/// assert!(!lf.is_ascii_lowercase());
/// assert!(!esc.is_ascii_lowercase());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[inline]
pub fn is_ascii_lowercase(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_lowercase()
}
/// Checks if the value is an ASCII alphanumeric character:
///
2019-06-14 19:24:38 +02:00
/// - U+0041 'A' ..= U+005A 'Z', or
/// - U+0061 'a' ..= U+007A 'z', or
/// - U+0030 '0' ..= U+0039 '9'.
///
/// # Examples
///
/// ```
/// let uppercase_a = 'A';
/// let uppercase_g = 'G';
/// let a = 'a';
/// let g = 'g';
/// let zero = '0';
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
///
/// assert!(uppercase_a.is_ascii_alphanumeric());
/// assert!(uppercase_g.is_ascii_alphanumeric());
/// assert!(a.is_ascii_alphanumeric());
/// assert!(g.is_ascii_alphanumeric());
/// assert!(zero.is_ascii_alphanumeric());
/// assert!(!percent.is_ascii_alphanumeric());
/// assert!(!space.is_ascii_alphanumeric());
/// assert!(!lf.is_ascii_alphanumeric());
/// assert!(!esc.is_ascii_alphanumeric());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[inline]
pub fn is_ascii_alphanumeric(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_alphanumeric()
}
/// Checks if the value is an ASCII decimal digit:
2019-06-14 19:24:38 +02:00
/// U+0030 '0' ..= U+0039 '9'.
///
/// # Examples
///
/// ```
/// let uppercase_a = 'A';
/// let uppercase_g = 'G';
/// let a = 'a';
/// let g = 'g';
/// let zero = '0';
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
///
/// assert!(!uppercase_a.is_ascii_digit());
/// assert!(!uppercase_g.is_ascii_digit());
/// assert!(!a.is_ascii_digit());
/// assert!(!g.is_ascii_digit());
/// assert!(zero.is_ascii_digit());
/// assert!(!percent.is_ascii_digit());
/// assert!(!space.is_ascii_digit());
/// assert!(!lf.is_ascii_digit());
/// assert!(!esc.is_ascii_digit());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[inline]
pub fn is_ascii_digit(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_digit()
}
/// Checks if the value is an ASCII hexadecimal digit:
///
2019-06-14 19:24:38 +02:00
/// - U+0030 '0' ..= U+0039 '9', or
/// - U+0041 'A' ..= U+0046 'F', or
/// - U+0061 'a' ..= U+0066 'f'.
///
/// # Examples
///
/// ```
/// let uppercase_a = 'A';
/// let uppercase_g = 'G';
/// let a = 'a';
/// let g = 'g';
/// let zero = '0';
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
///
/// assert!(uppercase_a.is_ascii_hexdigit());
/// assert!(!uppercase_g.is_ascii_hexdigit());
/// assert!(a.is_ascii_hexdigit());
/// assert!(!g.is_ascii_hexdigit());
/// assert!(zero.is_ascii_hexdigit());
/// assert!(!percent.is_ascii_hexdigit());
/// assert!(!space.is_ascii_hexdigit());
/// assert!(!lf.is_ascii_hexdigit());
/// assert!(!esc.is_ascii_hexdigit());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[inline]
pub fn is_ascii_hexdigit(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_hexdigit()
}
/// Checks if the value is an ASCII punctuation character:
///
2019-06-14 19:24:38 +02:00
/// - U+0021 ..= U+002F `! " # $ % & ' ( ) * + , - . /`, or
/// - U+003A ..= U+0040 `: ; < = > ? @`, or
/// - U+005B ..= U+0060 ``[ \ ] ^ _ ` ``, or
/// - U+007B ..= U+007E `{ | } ~`
///
/// # Examples
///
/// ```
/// let uppercase_a = 'A';
/// let uppercase_g = 'G';
/// let a = 'a';
/// let g = 'g';
/// let zero = '0';
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
///
/// assert!(!uppercase_a.is_ascii_punctuation());
/// assert!(!uppercase_g.is_ascii_punctuation());
/// assert!(!a.is_ascii_punctuation());
/// assert!(!g.is_ascii_punctuation());
/// assert!(!zero.is_ascii_punctuation());
/// assert!(percent.is_ascii_punctuation());
/// assert!(!space.is_ascii_punctuation());
/// assert!(!lf.is_ascii_punctuation());
/// assert!(!esc.is_ascii_punctuation());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[inline]
pub fn is_ascii_punctuation(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_punctuation()
}
/// Checks if the value is an ASCII graphic character:
2019-06-14 19:24:38 +02:00
/// U+0021 '!' ..= U+007E '~'.
///
/// # Examples
///
/// ```
/// let uppercase_a = 'A';
/// let uppercase_g = 'G';
/// let a = 'a';
/// let g = 'g';
/// let zero = '0';
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
///
/// assert!(uppercase_a.is_ascii_graphic());
/// assert!(uppercase_g.is_ascii_graphic());
/// assert!(a.is_ascii_graphic());
/// assert!(g.is_ascii_graphic());
/// assert!(zero.is_ascii_graphic());
/// assert!(percent.is_ascii_graphic());
/// assert!(!space.is_ascii_graphic());
/// assert!(!lf.is_ascii_graphic());
/// assert!(!esc.is_ascii_graphic());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[inline]
pub fn is_ascii_graphic(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_graphic()
}
/// Checks if the value is an ASCII whitespace character:
/// U+0020 SPACE, U+0009 HORIZONTAL TAB, U+000A LINE FEED,
/// U+000C FORM FEED, or U+000D CARRIAGE RETURN.
///
/// Rust uses the WhatWG Infra Standard's [definition of ASCII
/// whitespace][infra-aw]. There are several other definitions in
/// wide use. For instance, [the POSIX locale][pct] includes
/// U+000B VERTICAL TAB as well as all the above characters,
/// but—from the very same specification—[the default rule for
/// "field splitting" in the Bourne shell][bfs] considers *only*
/// SPACE, HORIZONTAL TAB, and LINE FEED as whitespace.
///
/// If you are writing a program that will process an existing
/// file format, check what that format's definition of whitespace is
/// before using this function.
///
/// [infra-aw]: https://infra.spec.whatwg.org/#ascii-whitespace
/// [pct]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01
/// [bfs]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05
///
/// # Examples
///
/// ```
/// let uppercase_a = 'A';
/// let uppercase_g = 'G';
/// let a = 'a';
/// let g = 'g';
/// let zero = '0';
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
///
/// assert!(!uppercase_a.is_ascii_whitespace());
/// assert!(!uppercase_g.is_ascii_whitespace());
/// assert!(!a.is_ascii_whitespace());
/// assert!(!g.is_ascii_whitespace());
/// assert!(!zero.is_ascii_whitespace());
/// assert!(!percent.is_ascii_whitespace());
/// assert!(space.is_ascii_whitespace());
/// assert!(lf.is_ascii_whitespace());
/// assert!(!esc.is_ascii_whitespace());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[inline]
pub fn is_ascii_whitespace(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_whitespace()
}
/// Checks if the value is an ASCII control character:
2019-06-14 19:24:38 +02:00
/// U+0000 NUL ..= U+001F UNIT SEPARATOR, or U+007F DELETE.
/// Note that most ASCII whitespace characters are control
/// characters, but SPACE is not.
///
/// # Examples
///
/// ```
/// let uppercase_a = 'A';
/// let uppercase_g = 'G';
/// let a = 'a';
/// let g = 'g';
/// let zero = '0';
/// let percent = '%';
/// let space = ' ';
/// let lf = '\n';
/// let esc: char = 0x1b_u8.into();
///
/// assert!(!uppercase_a.is_ascii_control());
/// assert!(!uppercase_g.is_ascii_control());
/// assert!(!a.is_ascii_control());
/// assert!(!g.is_ascii_control());
/// assert!(!zero.is_ascii_control());
/// assert!(!percent.is_ascii_control());
/// assert!(!space.is_ascii_control());
/// assert!(lf.is_ascii_control());
/// assert!(esc.is_ascii_control());
/// ```
#[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
#[inline]
pub fn is_ascii_control(&self) -> bool {
self.is_ascii() && (*self as u8).is_ascii_control()
}
2015-03-11 05:13:16 +01:00
}