]> git.proxmox.com Git - rustc.git/blame - src/libstd/ascii.rs
Imported Upstream version 1.3.0+dfsg1
[rustc.git] / src / libstd / ascii.rs
CommitLineData
1a4d82fc
JJ
1// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
1a4d82fc
JJ
10
11//! Operations on ASCII strings and characters
12
85aaf69f 13#![stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 14
85aaf69f
SL
15use prelude::v1::*;
16
c34b1796 17use ops::Range;
85aaf69f 18use mem;
1a4d82fc
JJ
19
20/// Extension methods for ASCII-subset only operations on owned strings
62682a34 21#[unstable(feature = "owned_ascii_ext",
85aaf69f 22 reason = "would prefer to do this in a more general way")]
c1a9b12d
SL
23#[deprecated(since = "1.3.0",
24 reason = "hasn't yet proved essential to be in the standard library")]
25#[allow(deprecated)]
1a4d82fc 26pub trait OwnedAsciiExt {
9346a6ac 27 /// Converts the string to ASCII upper case:
1a4d82fc
JJ
28 /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
29 /// but non-ASCII letters are unchanged.
30 fn into_ascii_uppercase(self) -> Self;
31
9346a6ac 32 /// Converts the string to ASCII lower case:
1a4d82fc
JJ
33 /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
34 /// but non-ASCII letters are unchanged.
35 fn into_ascii_lowercase(self) -> Self;
36}
37
c34b1796 38/// Extension methods for ASCII-subset only operations on string slices.
85aaf69f
SL
39#[stable(feature = "rust1", since = "1.0.0")]
40pub trait AsciiExt {
c34b1796 41 /// Container type for copied ASCII characters.
85aaf69f
SL
42 #[stable(feature = "rust1", since = "1.0.0")]
43 type Owned;
44
9346a6ac 45 /// Checks if within the ASCII range.
c34b1796
AL
46 ///
47 /// # Examples
48 ///
49 /// ```
50 /// use std::ascii::AsciiExt;
51 ///
52 /// let ascii = 'a';
53 /// let utf8 = '❤';
54 ///
55 /// assert_eq!(true, ascii.is_ascii());
56 /// assert_eq!(false, utf8.is_ascii())
57 /// ```
85aaf69f 58 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
59 fn is_ascii(&self) -> bool;
60
c34b1796
AL
61 /// Makes a copy of the string in ASCII upper case.
62 ///
1a4d82fc
JJ
63 /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
64 /// but non-ASCII letters are unchanged.
c34b1796
AL
65 ///
66 /// # Examples
67 ///
68 /// ```
69 /// use std::ascii::AsciiExt;
70 ///
71 /// let ascii = 'a';
72 /// let utf8 = '❤';
73 ///
74 /// assert_eq!('A', ascii.to_ascii_uppercase());
75 /// assert_eq!('❤', utf8.to_ascii_uppercase());
76 /// ```
85aaf69f
SL
77 #[stable(feature = "rust1", since = "1.0.0")]
78 fn to_ascii_uppercase(&self) -> Self::Owned;
1a4d82fc 79
c34b1796
AL
80 /// Makes a copy of the string in ASCII lower case.
81 ///
1a4d82fc
JJ
82 /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
83 /// but non-ASCII letters are unchanged.
c34b1796
AL
84 ///
85 /// # Examples
86 ///
87 /// ```
88 /// use std::ascii::AsciiExt;
89 ///
90 /// let ascii = 'A';
91 /// let utf8 = '❤';
92 ///
93 /// assert_eq!('a', ascii.to_ascii_lowercase());
94 /// assert_eq!('❤', utf8.to_ascii_lowercase());
95 /// ```
85aaf69f
SL
96 #[stable(feature = "rust1", since = "1.0.0")]
97 fn to_ascii_lowercase(&self) -> Self::Owned;
1a4d82fc 98
9346a6ac 99 /// Checks that two strings are an ASCII case-insensitive match.
c34b1796 100 ///
1a4d82fc
JJ
101 /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
102 /// but without allocating and copying temporary strings.
c34b1796
AL
103 ///
104 /// # Examples
105 ///
106 /// ```
107 /// use std::ascii::AsciiExt;
108 ///
109 /// let ascii1 = 'A';
110 /// let ascii2 = 'a';
111 /// let ascii3 = 'A';
112 /// let ascii4 = 'z';
113 ///
114 /// assert_eq!(true, ascii1.eq_ignore_ascii_case(&ascii2));
115 /// assert_eq!(true, ascii1.eq_ignore_ascii_case(&ascii3));
116 /// assert_eq!(false, ascii1.eq_ignore_ascii_case(&ascii4));
117 /// ```
85aaf69f 118 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 119 fn eq_ignore_ascii_case(&self, other: &Self) -> bool;
85aaf69f 120
9346a6ac 121 /// Converts this type to its ASCII upper case equivalent in-place.
85aaf69f
SL
122 ///
123 /// See `to_ascii_uppercase` for more information.
c34b1796
AL
124 ///
125 /// # Examples
126 ///
127 /// ```
c1a9b12d
SL
128 /// #![feature(ascii)]
129 ///
c34b1796
AL
130 /// use std::ascii::AsciiExt;
131 ///
132 /// let mut ascii = 'a';
133 ///
134 /// ascii.make_ascii_uppercase();
135 ///
136 /// assert_eq!('A', ascii);
137 /// ```
85aaf69f
SL
138 #[unstable(feature = "ascii")]
139 fn make_ascii_uppercase(&mut self);
140
9346a6ac 141 /// Converts this type to its ASCII lower case equivalent in-place.
85aaf69f
SL
142 ///
143 /// See `to_ascii_lowercase` for more information.
c34b1796
AL
144 ///
145 /// # Examples
146 ///
147 /// ```
c1a9b12d
SL
148 /// #![feature(ascii)]
149 ///
c34b1796
AL
150 /// use std::ascii::AsciiExt;
151 ///
152 /// let mut ascii = 'A';
153 ///
154 /// ascii.make_ascii_lowercase();
155 ///
156 /// assert_eq!('a', ascii);
157 /// ```
85aaf69f
SL
158 #[unstable(feature = "ascii")]
159 fn make_ascii_lowercase(&mut self);
1a4d82fc
JJ
160}
161
85aaf69f
SL
162#[stable(feature = "rust1", since = "1.0.0")]
163impl AsciiExt for str {
164 type Owned = String;
165
1a4d82fc
JJ
166 #[inline]
167 fn is_ascii(&self) -> bool {
168 self.bytes().all(|b| b.is_ascii())
169 }
170
171 #[inline]
c1a9b12d 172 #[allow(deprecated)]
1a4d82fc 173 fn to_ascii_uppercase(&self) -> String {
85aaf69f 174 self.to_string().into_ascii_uppercase()
1a4d82fc
JJ
175 }
176
177 #[inline]
c1a9b12d 178 #[allow(deprecated)]
1a4d82fc 179 fn to_ascii_lowercase(&self) -> String {
85aaf69f 180 self.to_string().into_ascii_lowercase()
1a4d82fc
JJ
181 }
182
183 #[inline]
184 fn eq_ignore_ascii_case(&self, other: &str) -> bool {
185 self.as_bytes().eq_ignore_ascii_case(other.as_bytes())
186 }
85aaf69f
SL
187
188 fn make_ascii_uppercase(&mut self) {
189 let me: &mut [u8] = unsafe { mem::transmute(self) };
190 me.make_ascii_uppercase()
191 }
192
193 fn make_ascii_lowercase(&mut self) {
194 let me: &mut [u8] = unsafe { mem::transmute(self) };
195 me.make_ascii_lowercase()
196 }
1a4d82fc
JJ
197}
198
c1a9b12d 199#[allow(deprecated)]
1a4d82fc
JJ
200impl OwnedAsciiExt for String {
201 #[inline]
202 fn into_ascii_uppercase(self) -> String {
203 // Vec<u8>::into_ascii_uppercase() preserves the UTF-8 invariant.
204 unsafe { String::from_utf8_unchecked(self.into_bytes().into_ascii_uppercase()) }
205 }
206
207 #[inline]
208 fn into_ascii_lowercase(self) -> String {
209 // Vec<u8>::into_ascii_lowercase() preserves the UTF-8 invariant.
210 unsafe { String::from_utf8_unchecked(self.into_bytes().into_ascii_lowercase()) }
211 }
212}
213
85aaf69f
SL
214#[stable(feature = "rust1", since = "1.0.0")]
215impl AsciiExt for [u8] {
216 type Owned = Vec<u8>;
1a4d82fc
JJ
217 #[inline]
218 fn is_ascii(&self) -> bool {
219 self.iter().all(|b| b.is_ascii())
220 }
221
222 #[inline]
c1a9b12d 223 #[allow(deprecated)]
1a4d82fc 224 fn to_ascii_uppercase(&self) -> Vec<u8> {
85aaf69f 225 self.to_vec().into_ascii_uppercase()
1a4d82fc
JJ
226 }
227
228 #[inline]
c1a9b12d 229 #[allow(deprecated)]
1a4d82fc 230 fn to_ascii_lowercase(&self) -> Vec<u8> {
85aaf69f 231 self.to_vec().into_ascii_lowercase()
1a4d82fc
JJ
232 }
233
234 #[inline]
235 fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool {
236 self.len() == other.len() &&
62682a34 237 self.iter().zip(other).all(|(a, b)| {
1a4d82fc
JJ
238 a.eq_ignore_ascii_case(b)
239 })
240 }
85aaf69f
SL
241
242 fn make_ascii_uppercase(&mut self) {
243 for byte in self {
244 byte.make_ascii_uppercase();
245 }
246 }
247
248 fn make_ascii_lowercase(&mut self) {
249 for byte in self {
250 byte.make_ascii_lowercase();
251 }
252 }
1a4d82fc
JJ
253}
254
c1a9b12d 255#[allow(deprecated)]
1a4d82fc
JJ
256impl OwnedAsciiExt for Vec<u8> {
257 #[inline]
258 fn into_ascii_uppercase(mut self) -> Vec<u8> {
85aaf69f 259 self.make_ascii_uppercase();
1a4d82fc
JJ
260 self
261 }
262
263 #[inline]
264 fn into_ascii_lowercase(mut self) -> Vec<u8> {
85aaf69f 265 self.make_ascii_lowercase();
1a4d82fc
JJ
266 self
267 }
268}
269
85aaf69f 270#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 271impl AsciiExt for u8 {
85aaf69f 272 type Owned = u8;
1a4d82fc 273 #[inline]
c34b1796 274 fn is_ascii(&self) -> bool { *self & 128 == 0 }
1a4d82fc 275 #[inline]
85aaf69f 276 fn to_ascii_uppercase(&self) -> u8 { ASCII_UPPERCASE_MAP[*self as usize] }
1a4d82fc 277 #[inline]
85aaf69f 278 fn to_ascii_lowercase(&self) -> u8 { ASCII_LOWERCASE_MAP[*self as usize] }
1a4d82fc
JJ
279 #[inline]
280 fn eq_ignore_ascii_case(&self, other: &u8) -> bool {
281 self.to_ascii_lowercase() == other.to_ascii_lowercase()
282 }
85aaf69f
SL
283 #[inline]
284 fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); }
285 #[inline]
286 fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); }
1a4d82fc
JJ
287}
288
85aaf69f 289#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 290impl AsciiExt for char {
85aaf69f 291 type Owned = char;
1a4d82fc
JJ
292 #[inline]
293 fn is_ascii(&self) -> bool {
294 *self as u32 <= 0x7F
295 }
296
297 #[inline]
298 fn to_ascii_uppercase(&self) -> char {
299 if self.is_ascii() {
300 (*self as u8).to_ascii_uppercase() as char
301 } else {
302 *self
303 }
304 }
305
306 #[inline]
307 fn to_ascii_lowercase(&self) -> char {
308 if self.is_ascii() {
309 (*self as u8).to_ascii_lowercase() as char
310 } else {
311 *self
312 }
313 }
314
315 #[inline]
316 fn eq_ignore_ascii_case(&self, other: &char) -> bool {
317 self.to_ascii_lowercase() == other.to_ascii_lowercase()
318 }
85aaf69f
SL
319
320 #[inline]
321 fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); }
322 #[inline]
323 fn make_ascii_lowercase(&mut self) { *self = self.to_ascii_lowercase(); }
324}
325
326/// An iterator over the escaped version of a byte, constructed via
327/// `std::ascii::escape_default`.
328#[stable(feature = "rust1", since = "1.0.0")]
329pub struct EscapeDefault {
330 range: Range<usize>,
331 data: [u8; 4],
1a4d82fc
JJ
332}
333
c34b1796 334/// Returns an iterator that produces an escaped version of a `u8`.
1a4d82fc
JJ
335///
336/// The default is chosen with a bias toward producing literals that are
337/// legal in a variety of languages, including C++11 and similar C-family
338/// languages. The exact rules are:
339///
340/// - Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
341/// - Single-quote, double-quote and backslash chars are backslash-escaped.
342/// - Any other chars in the range [0x20,0x7e] are not escaped.
85aaf69f 343/// - Any other chars are given hex escapes of the form '\xNN'.
1a4d82fc 344/// - Unicode escapes are never generated by this function.
c34b1796
AL
345///
346/// # Examples
347///
348/// ```
349/// use std::ascii;
350///
351/// let escaped = ascii::escape_default(b'0').next().unwrap();
352/// assert_eq!(b'0', escaped);
353///
354/// let mut escaped = ascii::escape_default(b'\t');
355///
356/// assert_eq!(b'\\', escaped.next().unwrap());
357/// assert_eq!(b't', escaped.next().unwrap());
358/// ```
85aaf69f
SL
359#[stable(feature = "rust1", since = "1.0.0")]
360pub fn escape_default(c: u8) -> EscapeDefault {
361 let (data, len) = match c {
362 b'\t' => ([b'\\', b't', 0, 0], 2),
363 b'\r' => ([b'\\', b'r', 0, 0], 2),
364 b'\n' => ([b'\\', b'n', 0, 0], 2),
365 b'\\' => ([b'\\', b'\\', 0, 0], 2),
366 b'\'' => ([b'\\', b'\'', 0, 0], 2),
367 b'"' => ([b'\\', b'"', 0, 0], 2),
368 b'\x20' ... b'\x7e' => ([c, 0, 0, 0], 1),
369 _ => ([b'\\', b'x', hexify(c >> 4), hexify(c & 0xf)], 4),
370 };
371
c34b1796 372 return EscapeDefault { range: (0.. len), data: data };
85aaf69f
SL
373
374 fn hexify(b: u8) -> u8 {
375 match b {
376 0 ... 9 => b'0' + b,
377 _ => b'a' + b - 10,
1a4d82fc
JJ
378 }
379 }
380}
381
85aaf69f
SL
382#[stable(feature = "rust1", since = "1.0.0")]
383impl Iterator for EscapeDefault {
384 type Item = u8;
385 fn next(&mut self) -> Option<u8> { self.range.next().map(|i| self.data[i]) }
386 fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() }
387}
388#[stable(feature = "rust1", since = "1.0.0")]
389impl DoubleEndedIterator for EscapeDefault {
390 fn next_back(&mut self) -> Option<u8> {
391 self.range.next_back().map(|i| self.data[i])
392 }
393}
394#[stable(feature = "rust1", since = "1.0.0")]
395impl ExactSizeIterator for EscapeDefault {}
396
1a4d82fc
JJ
397static ASCII_LOWERCASE_MAP: [u8; 256] = [
398 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
399 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
400 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
401 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
402 b' ', b'!', b'"', b'#', b'$', b'%', b'&', b'\'',
403 b'(', b')', b'*', b'+', b',', b'-', b'.', b'/',
404 b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7',
405 b'8', b'9', b':', b';', b'<', b'=', b'>', b'?',
406 b'@',
407
408 b'a', b'b', b'c', b'd', b'e', b'f', b'g',
409 b'h', b'i', b'j', b'k', b'l', b'm', b'n', b'o',
410 b'p', b'q', b'r', b's', b't', b'u', b'v', b'w',
411 b'x', b'y', b'z',
412
413 b'[', b'\\', b']', b'^', b'_',
414 b'`', b'a', b'b', b'c', b'd', b'e', b'f', b'g',
415 b'h', b'i', b'j', b'k', b'l', b'm', b'n', b'o',
416 b'p', b'q', b'r', b's', b't', b'u', b'v', b'w',
417 b'x', b'y', b'z', b'{', b'|', b'}', b'~', 0x7f,
418 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
419 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
420 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
421 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
422 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
423 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
424 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
425 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
426 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
427 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
428 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
429 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
430 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
431 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
432 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
433 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
434];
435
436static ASCII_UPPERCASE_MAP: [u8; 256] = [
437 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
438 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
439 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
440 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
441 b' ', b'!', b'"', b'#', b'$', b'%', b'&', b'\'',
442 b'(', b')', b'*', b'+', b',', b'-', b'.', b'/',
443 b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7',
444 b'8', b'9', b':', b';', b'<', b'=', b'>', b'?',
445 b'@', b'A', b'B', b'C', b'D', b'E', b'F', b'G',
446 b'H', b'I', b'J', b'K', b'L', b'M', b'N', b'O',
447 b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W',
448 b'X', b'Y', b'Z', b'[', b'\\', b']', b'^', b'_',
449 b'`',
450
451 b'A', b'B', b'C', b'D', b'E', b'F', b'G',
452 b'H', b'I', b'J', b'K', b'L', b'M', b'N', b'O',
453 b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W',
454 b'X', b'Y', b'Z',
455
456 b'{', b'|', b'}', b'~', 0x7f,
457 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
458 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
459 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
460 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
461 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
462 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
463 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
464 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
465 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
466 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
467 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
468 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
469 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
470 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
471 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
472 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
473];
474
475
476#[cfg(test)]
477mod tests {
478 use prelude::v1::*;
479 use super::*;
480 use char::from_u32;
481
482 #[test]
c1a9b12d
SL
483 fn test_is_ascii() {
484 assert!(b"".is_ascii());
485 assert!(b"banana\0\x7F".is_ascii());
486 assert!(b"banana\0\x7F".iter().all(|b| b.is_ascii()));
487 assert!(!b"Vi\xe1\xbb\x87t Nam".is_ascii());
488 assert!(!b"Vi\xe1\xbb\x87t Nam".iter().all(|b| b.is_ascii()));
489 assert!(!b"\xe1\xbb\x87".iter().any(|b| b.is_ascii()));
1a4d82fc 490
1a4d82fc 491 assert!("".is_ascii());
c1a9b12d
SL
492 assert!("banana\0\u{7F}".is_ascii());
493 assert!("banana\0\u{7F}".chars().all(|c| c.is_ascii()));
494 assert!(!"ประเทศไทย中华Việt Nam".chars().all(|c| c.is_ascii()));
495 assert!(!"ประเทศไทย中华ệ ".chars().any(|c| c.is_ascii()));
1a4d82fc
JJ
496 }
497
498 #[test]
499 fn test_to_ascii_uppercase() {
500 assert_eq!("url()URL()uRl()ürl".to_ascii_uppercase(), "URL()URL()URL()üRL");
501 assert_eq!("hıKß".to_ascii_uppercase(), "HıKß");
502
c34b1796 503 for i in 0..501 {
1a4d82fc
JJ
504 let upper = if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 }
505 else { i };
506 assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_uppercase(),
507 (from_u32(upper).unwrap()).to_string());
1a4d82fc
JJ
508 }
509 }
510
511 #[test]
512 fn test_to_ascii_lowercase() {
513 assert_eq!("url()URL()uRl()Ürl".to_ascii_lowercase(), "url()url()url()Ürl");
514 // Dotted capital I, Kelvin sign, Sharp S.
515 assert_eq!("HİKß".to_ascii_lowercase(), "hİKß");
516
c34b1796 517 for i in 0..501 {
1a4d82fc
JJ
518 let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 }
519 else { i };
520 assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_lowercase(),
521 (from_u32(lower).unwrap()).to_string());
1a4d82fc
JJ
522 }
523 }
524
525 #[test]
526 fn test_into_ascii_uppercase() {
527 assert_eq!(("url()URL()uRl()ürl".to_string()).into_ascii_uppercase(),
528 "URL()URL()URL()üRL".to_string());
529 assert_eq!(("hıKß".to_string()).into_ascii_uppercase(), "HıKß");
530
c34b1796 531 for i in 0..501 {
1a4d82fc
JJ
532 let upper = if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 }
533 else { i };
534 assert_eq!((from_u32(i).unwrap()).to_string().into_ascii_uppercase(),
535 (from_u32(upper).unwrap()).to_string());
1a4d82fc
JJ
536 }
537 }
538
539 #[test]
540 fn test_into_ascii_lowercase() {
541 assert_eq!(("url()URL()uRl()Ürl".to_string()).into_ascii_lowercase(),
542 "url()url()url()Ürl");
543 // Dotted capital I, Kelvin sign, Sharp S.
544 assert_eq!(("HİKß".to_string()).into_ascii_lowercase(), "hİKß");
545
c34b1796 546 for i in 0..501 {
1a4d82fc
JJ
547 let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 }
548 else { i };
549 assert_eq!((from_u32(i).unwrap()).to_string().into_ascii_lowercase(),
550 (from_u32(lower).unwrap()).to_string());
1a4d82fc
JJ
551 }
552 }
553
c1a9b12d
SL
554 #[test]
555 fn test_make_ascii_lower_case() {
556 macro_rules! test {
557 ($from: expr, $to: expr) => {
558 {
559 let mut x = $from;
560 x.make_ascii_lowercase();
561 assert_eq!(x, $to);
562 }
563 }
564 }
565 test!(b'A', b'a');
566 test!(b'a', b'a');
567 test!(b'!', b'!');
568 test!('A', 'a');
569 test!('À', 'À');
570 test!('a', 'a');
571 test!('!', '!');
572 test!(b"H\xc3\x89".to_vec(), b"h\xc3\x89");
573 test!("HİKß".to_string(), "hİKß");
574 }
575
576
577 #[test]
578 fn test_make_ascii_upper_case() {
579 macro_rules! test {
580 ($from: expr, $to: expr) => {
581 {
582 let mut x = $from;
583 x.make_ascii_uppercase();
584 assert_eq!(x, $to);
585 }
586 }
587 }
588 test!(b'a', b'A');
589 test!(b'A', b'A');
590 test!(b'!', b'!');
591 test!('a', 'A');
592 test!('à', 'à');
593 test!('A', 'A');
594 test!('!', '!');
595 test!(b"h\xc3\xa9".to_vec(), b"H\xc3\xa9");
596 test!("hıKß".to_string(), "HıKß");
597
598 let mut x = "Hello".to_string();
599 x[..3].make_ascii_uppercase(); // Test IndexMut on String.
600 assert_eq!(x, "HELlo")
601 }
602
1a4d82fc
JJ
603 #[test]
604 fn test_eq_ignore_ascii_case() {
605 assert!("url()URL()uRl()Ürl".eq_ignore_ascii_case("url()url()url()Ürl"));
606 assert!(!"Ürl".eq_ignore_ascii_case("ürl"));
607 // Dotted capital I, Kelvin sign, Sharp S.
608 assert!("HİKß".eq_ignore_ascii_case("hİKß"));
609 assert!(!"İ".eq_ignore_ascii_case("i"));
610 assert!(!"K".eq_ignore_ascii_case("k"));
611 assert!(!"ß".eq_ignore_ascii_case("s"));
612
c34b1796 613 for i in 0..501 {
85aaf69f
SL
614 let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 }
615 else { i };
1a4d82fc 616 assert!((from_u32(i).unwrap()).to_string().eq_ignore_ascii_case(
85aaf69f 617 &from_u32(lower).unwrap().to_string()));
1a4d82fc
JJ
618 }
619 }
620}