1use crate::mem::transmute;
7use crate::{assert_unsafe_precondition, fmt};
8
9#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
58#[unstable(feature = "ascii_char", issue = "110998")]
59#[repr(u8)]
60pub enum AsciiChar {
61 #[unstable(feature = "ascii_char_variants", issue = "110998")]
63 Null = 0,
64 #[unstable(feature = "ascii_char_variants", issue = "110998")]
66 StartOfHeading = 1,
67 #[unstable(feature = "ascii_char_variants", issue = "110998")]
69 StartOfText = 2,
70 #[unstable(feature = "ascii_char_variants", issue = "110998")]
72 EndOfText = 3,
73 #[unstable(feature = "ascii_char_variants", issue = "110998")]
75 EndOfTransmission = 4,
76 #[unstable(feature = "ascii_char_variants", issue = "110998")]
78 Enquiry = 5,
79 #[unstable(feature = "ascii_char_variants", issue = "110998")]
81 Acknowledge = 6,
82 #[unstable(feature = "ascii_char_variants", issue = "110998")]
84 Bell = 7,
85 #[unstable(feature = "ascii_char_variants", issue = "110998")]
87 Backspace = 8,
88 #[unstable(feature = "ascii_char_variants", issue = "110998")]
90 CharacterTabulation = 9,
91 #[unstable(feature = "ascii_char_variants", issue = "110998")]
93 LineFeed = 10,
94 #[unstable(feature = "ascii_char_variants", issue = "110998")]
96 LineTabulation = 11,
97 #[unstable(feature = "ascii_char_variants", issue = "110998")]
99 FormFeed = 12,
100 #[unstable(feature = "ascii_char_variants", issue = "110998")]
102 CarriageReturn = 13,
103 #[unstable(feature = "ascii_char_variants", issue = "110998")]
105 ShiftOut = 14,
106 #[unstable(feature = "ascii_char_variants", issue = "110998")]
108 ShiftIn = 15,
109 #[unstable(feature = "ascii_char_variants", issue = "110998")]
111 DataLinkEscape = 16,
112 #[unstable(feature = "ascii_char_variants", issue = "110998")]
114 DeviceControlOne = 17,
115 #[unstable(feature = "ascii_char_variants", issue = "110998")]
117 DeviceControlTwo = 18,
118 #[unstable(feature = "ascii_char_variants", issue = "110998")]
120 DeviceControlThree = 19,
121 #[unstable(feature = "ascii_char_variants", issue = "110998")]
123 DeviceControlFour = 20,
124 #[unstable(feature = "ascii_char_variants", issue = "110998")]
126 NegativeAcknowledge = 21,
127 #[unstable(feature = "ascii_char_variants", issue = "110998")]
129 SynchronousIdle = 22,
130 #[unstable(feature = "ascii_char_variants", issue = "110998")]
132 EndOfTransmissionBlock = 23,
133 #[unstable(feature = "ascii_char_variants", issue = "110998")]
135 Cancel = 24,
136 #[unstable(feature = "ascii_char_variants", issue = "110998")]
138 EndOfMedium = 25,
139 #[unstable(feature = "ascii_char_variants", issue = "110998")]
141 Substitute = 26,
142 #[unstable(feature = "ascii_char_variants", issue = "110998")]
144 Escape = 27,
145 #[unstable(feature = "ascii_char_variants", issue = "110998")]
147 InformationSeparatorFour = 28,
148 #[unstable(feature = "ascii_char_variants", issue = "110998")]
150 InformationSeparatorThree = 29,
151 #[unstable(feature = "ascii_char_variants", issue = "110998")]
153 InformationSeparatorTwo = 30,
154 #[unstable(feature = "ascii_char_variants", issue = "110998")]
156 InformationSeparatorOne = 31,
157 #[unstable(feature = "ascii_char_variants", issue = "110998")]
159 Space = 32,
160 #[unstable(feature = "ascii_char_variants", issue = "110998")]
162 ExclamationMark = 33,
163 #[unstable(feature = "ascii_char_variants", issue = "110998")]
165 QuotationMark = 34,
166 #[unstable(feature = "ascii_char_variants", issue = "110998")]
168 NumberSign = 35,
169 #[unstable(feature = "ascii_char_variants", issue = "110998")]
171 DollarSign = 36,
172 #[unstable(feature = "ascii_char_variants", issue = "110998")]
174 PercentSign = 37,
175 #[unstable(feature = "ascii_char_variants", issue = "110998")]
177 Ampersand = 38,
178 #[unstable(feature = "ascii_char_variants", issue = "110998")]
180 Apostrophe = 39,
181 #[unstable(feature = "ascii_char_variants", issue = "110998")]
183 LeftParenthesis = 40,
184 #[unstable(feature = "ascii_char_variants", issue = "110998")]
186 RightParenthesis = 41,
187 #[unstable(feature = "ascii_char_variants", issue = "110998")]
189 Asterisk = 42,
190 #[unstable(feature = "ascii_char_variants", issue = "110998")]
192 PlusSign = 43,
193 #[unstable(feature = "ascii_char_variants", issue = "110998")]
195 Comma = 44,
196 #[unstable(feature = "ascii_char_variants", issue = "110998")]
198 HyphenMinus = 45,
199 #[unstable(feature = "ascii_char_variants", issue = "110998")]
201 FullStop = 46,
202 #[unstable(feature = "ascii_char_variants", issue = "110998")]
204 Solidus = 47,
205 #[unstable(feature = "ascii_char_variants", issue = "110998")]
207 Digit0 = 48,
208 #[unstable(feature = "ascii_char_variants", issue = "110998")]
210 Digit1 = 49,
211 #[unstable(feature = "ascii_char_variants", issue = "110998")]
213 Digit2 = 50,
214 #[unstable(feature = "ascii_char_variants", issue = "110998")]
216 Digit3 = 51,
217 #[unstable(feature = "ascii_char_variants", issue = "110998")]
219 Digit4 = 52,
220 #[unstable(feature = "ascii_char_variants", issue = "110998")]
222 Digit5 = 53,
223 #[unstable(feature = "ascii_char_variants", issue = "110998")]
225 Digit6 = 54,
226 #[unstable(feature = "ascii_char_variants", issue = "110998")]
228 Digit7 = 55,
229 #[unstable(feature = "ascii_char_variants", issue = "110998")]
231 Digit8 = 56,
232 #[unstable(feature = "ascii_char_variants", issue = "110998")]
234 Digit9 = 57,
235 #[unstable(feature = "ascii_char_variants", issue = "110998")]
237 Colon = 58,
238 #[unstable(feature = "ascii_char_variants", issue = "110998")]
240 Semicolon = 59,
241 #[unstable(feature = "ascii_char_variants", issue = "110998")]
243 LessThanSign = 60,
244 #[unstable(feature = "ascii_char_variants", issue = "110998")]
246 EqualsSign = 61,
247 #[unstable(feature = "ascii_char_variants", issue = "110998")]
249 GreaterThanSign = 62,
250 #[unstable(feature = "ascii_char_variants", issue = "110998")]
252 QuestionMark = 63,
253 #[unstable(feature = "ascii_char_variants", issue = "110998")]
255 CommercialAt = 64,
256 #[unstable(feature = "ascii_char_variants", issue = "110998")]
258 CapitalA = 65,
259 #[unstable(feature = "ascii_char_variants", issue = "110998")]
261 CapitalB = 66,
262 #[unstable(feature = "ascii_char_variants", issue = "110998")]
264 CapitalC = 67,
265 #[unstable(feature = "ascii_char_variants", issue = "110998")]
267 CapitalD = 68,
268 #[unstable(feature = "ascii_char_variants", issue = "110998")]
270 CapitalE = 69,
271 #[unstable(feature = "ascii_char_variants", issue = "110998")]
273 CapitalF = 70,
274 #[unstable(feature = "ascii_char_variants", issue = "110998")]
276 CapitalG = 71,
277 #[unstable(feature = "ascii_char_variants", issue = "110998")]
279 CapitalH = 72,
280 #[unstable(feature = "ascii_char_variants", issue = "110998")]
282 CapitalI = 73,
283 #[unstable(feature = "ascii_char_variants", issue = "110998")]
285 CapitalJ = 74,
286 #[unstable(feature = "ascii_char_variants", issue = "110998")]
288 CapitalK = 75,
289 #[unstable(feature = "ascii_char_variants", issue = "110998")]
291 CapitalL = 76,
292 #[unstable(feature = "ascii_char_variants", issue = "110998")]
294 CapitalM = 77,
295 #[unstable(feature = "ascii_char_variants", issue = "110998")]
297 CapitalN = 78,
298 #[unstable(feature = "ascii_char_variants", issue = "110998")]
300 CapitalO = 79,
301 #[unstable(feature = "ascii_char_variants", issue = "110998")]
303 CapitalP = 80,
304 #[unstable(feature = "ascii_char_variants", issue = "110998")]
306 CapitalQ = 81,
307 #[unstable(feature = "ascii_char_variants", issue = "110998")]
309 CapitalR = 82,
310 #[unstable(feature = "ascii_char_variants", issue = "110998")]
312 CapitalS = 83,
313 #[unstable(feature = "ascii_char_variants", issue = "110998")]
315 CapitalT = 84,
316 #[unstable(feature = "ascii_char_variants", issue = "110998")]
318 CapitalU = 85,
319 #[unstable(feature = "ascii_char_variants", issue = "110998")]
321 CapitalV = 86,
322 #[unstable(feature = "ascii_char_variants", issue = "110998")]
324 CapitalW = 87,
325 #[unstable(feature = "ascii_char_variants", issue = "110998")]
327 CapitalX = 88,
328 #[unstable(feature = "ascii_char_variants", issue = "110998")]
330 CapitalY = 89,
331 #[unstable(feature = "ascii_char_variants", issue = "110998")]
333 CapitalZ = 90,
334 #[unstable(feature = "ascii_char_variants", issue = "110998")]
336 LeftSquareBracket = 91,
337 #[unstable(feature = "ascii_char_variants", issue = "110998")]
339 ReverseSolidus = 92,
340 #[unstable(feature = "ascii_char_variants", issue = "110998")]
342 RightSquareBracket = 93,
343 #[unstable(feature = "ascii_char_variants", issue = "110998")]
345 CircumflexAccent = 94,
346 #[unstable(feature = "ascii_char_variants", issue = "110998")]
348 LowLine = 95,
349 #[unstable(feature = "ascii_char_variants", issue = "110998")]
351 GraveAccent = 96,
352 #[unstable(feature = "ascii_char_variants", issue = "110998")]
354 SmallA = 97,
355 #[unstable(feature = "ascii_char_variants", issue = "110998")]
357 SmallB = 98,
358 #[unstable(feature = "ascii_char_variants", issue = "110998")]
360 SmallC = 99,
361 #[unstable(feature = "ascii_char_variants", issue = "110998")]
363 SmallD = 100,
364 #[unstable(feature = "ascii_char_variants", issue = "110998")]
366 SmallE = 101,
367 #[unstable(feature = "ascii_char_variants", issue = "110998")]
369 SmallF = 102,
370 #[unstable(feature = "ascii_char_variants", issue = "110998")]
372 SmallG = 103,
373 #[unstable(feature = "ascii_char_variants", issue = "110998")]
375 SmallH = 104,
376 #[unstable(feature = "ascii_char_variants", issue = "110998")]
378 SmallI = 105,
379 #[unstable(feature = "ascii_char_variants", issue = "110998")]
381 SmallJ = 106,
382 #[unstable(feature = "ascii_char_variants", issue = "110998")]
384 SmallK = 107,
385 #[unstable(feature = "ascii_char_variants", issue = "110998")]
387 SmallL = 108,
388 #[unstable(feature = "ascii_char_variants", issue = "110998")]
390 SmallM = 109,
391 #[unstable(feature = "ascii_char_variants", issue = "110998")]
393 SmallN = 110,
394 #[unstable(feature = "ascii_char_variants", issue = "110998")]
396 SmallO = 111,
397 #[unstable(feature = "ascii_char_variants", issue = "110998")]
399 SmallP = 112,
400 #[unstable(feature = "ascii_char_variants", issue = "110998")]
402 SmallQ = 113,
403 #[unstable(feature = "ascii_char_variants", issue = "110998")]
405 SmallR = 114,
406 #[unstable(feature = "ascii_char_variants", issue = "110998")]
408 SmallS = 115,
409 #[unstable(feature = "ascii_char_variants", issue = "110998")]
411 SmallT = 116,
412 #[unstable(feature = "ascii_char_variants", issue = "110998")]
414 SmallU = 117,
415 #[unstable(feature = "ascii_char_variants", issue = "110998")]
417 SmallV = 118,
418 #[unstable(feature = "ascii_char_variants", issue = "110998")]
420 SmallW = 119,
421 #[unstable(feature = "ascii_char_variants", issue = "110998")]
423 SmallX = 120,
424 #[unstable(feature = "ascii_char_variants", issue = "110998")]
426 SmallY = 121,
427 #[unstable(feature = "ascii_char_variants", issue = "110998")]
429 SmallZ = 122,
430 #[unstable(feature = "ascii_char_variants", issue = "110998")]
432 LeftCurlyBracket = 123,
433 #[unstable(feature = "ascii_char_variants", issue = "110998")]
435 VerticalLine = 124,
436 #[unstable(feature = "ascii_char_variants", issue = "110998")]
438 RightCurlyBracket = 125,
439 #[unstable(feature = "ascii_char_variants", issue = "110998")]
441 Tilde = 126,
442 #[unstable(feature = "ascii_char_variants", issue = "110998")]
444 Delete = 127,
445}
446
447impl AsciiChar {
448 #[unstable(feature = "ascii_char", issue = "110998")]
451 #[inline]
452 pub const fn from_u8(b: u8) -> Option<Self> {
453 if b <= 127 {
454 Some(unsafe { Self::from_u8_unchecked(b) })
456 } else {
457 None
458 }
459 }
460
461 #[unstable(feature = "ascii_char", issue = "110998")]
468 #[inline]
469 pub const unsafe fn from_u8_unchecked(b: u8) -> Self {
470 unsafe { transmute(b) }
472 }
473
474 #[unstable(feature = "ascii_char", issue = "110998")]
479 #[inline]
480 pub const fn digit(d: u8) -> Option<Self> {
481 if d < 10 {
482 Some(unsafe { Self::digit_unchecked(d) })
484 } else {
485 None
486 }
487 }
488
489 #[unstable(feature = "ascii_char", issue = "110998")]
505 #[inline]
506 pub const unsafe fn digit_unchecked(d: u8) -> Self {
507 assert_unsafe_precondition!(
508 check_language_ub,
509 "`ascii::Char::digit_unchecked` input cannot exceed 9.",
510 (d: u8 = d) => d < 10
511 );
512
513 unsafe {
517 let byte = b'0'.unchecked_add(d);
518 Self::from_u8_unchecked(byte)
519 }
520 }
521
522 #[unstable(feature = "ascii_char", issue = "110998")]
524 #[inline]
525 pub const fn to_u8(self) -> u8 {
526 self as u8
527 }
528
529 #[unstable(feature = "ascii_char", issue = "110998")]
531 #[inline]
532 pub const fn to_char(self) -> char {
533 self as u8 as char
534 }
535
536 #[unstable(feature = "ascii_char", issue = "110998")]
538 #[inline]
539 pub const fn as_str(&self) -> &str {
540 crate::slice::from_ref(self).as_str()
541 }
542}
543
544macro_rules! into_int_impl {
545 ($($ty:ty)*) => {
546 $(
547 #[unstable(feature = "ascii_char", issue = "110998")]
548 impl From<AsciiChar> for $ty {
549 #[inline]
550 fn from(chr: AsciiChar) -> $ty {
551 chr as u8 as $ty
552 }
553 }
554 )*
555 }
556}
557
558into_int_impl!(u8 u16 u32 u64 u128 char);
559
560impl [AsciiChar] {
561 #[unstable(feature = "ascii_char", issue = "110998")]
563 #[inline]
564 pub const fn as_str(&self) -> &str {
565 let ascii_ptr: *const Self = self;
566 let str_ptr = ascii_ptr as *const str;
567 unsafe { &*str_ptr }
570 }
571
572 #[unstable(feature = "ascii_char", issue = "110998")]
574 #[inline]
575 pub const fn as_bytes(&self) -> &[u8] {
576 self.as_str().as_bytes()
577 }
578}
579
580#[unstable(feature = "ascii_char", issue = "110998")]
581impl fmt::Display for AsciiChar {
582 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
583 <str as fmt::Display>::fmt(self.as_str(), f)
584 }
585}
586
587#[unstable(feature = "ascii_char", issue = "110998")]
588impl fmt::Debug for AsciiChar {
589 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
590 use AsciiChar::{Apostrophe, Null, ReverseSolidus as Backslash};
591
592 fn backslash(a: AsciiChar) -> ([AsciiChar; 6], usize) {
593 ([Apostrophe, Backslash, a, Apostrophe, Null, Null], 4)
594 }
595
596 let (buf, len) = match self {
597 AsciiChar::Null => backslash(AsciiChar::Digit0),
598 AsciiChar::CharacterTabulation => backslash(AsciiChar::SmallT),
599 AsciiChar::CarriageReturn => backslash(AsciiChar::SmallR),
600 AsciiChar::LineFeed => backslash(AsciiChar::SmallN),
601 AsciiChar::ReverseSolidus => backslash(AsciiChar::ReverseSolidus),
602 AsciiChar::Apostrophe => backslash(AsciiChar::Apostrophe),
603 _ if self.to_u8().is_ascii_control() => {
604 const HEX_DIGITS: [AsciiChar; 16] = *b"0123456789abcdef".as_ascii().unwrap();
605
606 let byte = self.to_u8();
607 let hi = HEX_DIGITS[usize::from(byte >> 4)];
608 let lo = HEX_DIGITS[usize::from(byte & 0xf)];
609 ([Apostrophe, Backslash, AsciiChar::SmallX, hi, lo, Apostrophe], 6)
610 }
611 _ => ([Apostrophe, *self, Apostrophe, Null, Null, Null], 3),
612 };
613
614 f.write_str(buf[..len].as_str())
615 }
616}