@@ -360,6 +360,32 @@ impl AsciiChar {
360
360
ALL [ ch as usize ]
361
361
}
362
362
363
+ /// Create an `AsciiChar` from a `char`, in a `const fn` way.
364
+ ///
365
+ /// Within non-`const fn` functions the more general
366
+ /// [`from_ascii()`](#method.from_ascii) should be used instead.
367
+ ///
368
+ /// # Examples
369
+ /// ```
370
+ /// # use ascii::AsciiChar;
371
+ /// assert!(AsciiChar::try_new('-').is_ok());
372
+ /// assert!(AsciiChar::try_new('—').is_err());
373
+ /// assert_eq!(AsciiChar::try_new('\x7f'), Ok(AsciiChar::DEL));
374
+ /// ```
375
+ ///
376
+ /// # Errors
377
+ ///
378
+ /// Fails for non-ASCII characters.
379
+ #[ inline]
380
+ pub const fn try_new ( ch : char ) -> Result < Self , ToAsciiCharError > {
381
+ unsafe {
382
+ match ch as u32 {
383
+ 0 ..=127 => Ok ( mem:: transmute ( ch as u8 ) ) ,
384
+ _ => Err ( ToAsciiCharError ( ( ) ) ) ,
385
+ }
386
+ }
387
+ }
388
+
363
389
/// Constructs an ASCII character from a `u8`, `char` or other character
364
390
/// type without any checks.
365
391
///
@@ -375,9 +401,9 @@ impl AsciiChar {
375
401
/// and `Some(AsciiChar::from_ascii_unchecked(128))` might be `None`.
376
402
#[ inline]
377
403
#[ must_use]
378
- pub unsafe fn from_ascii_unchecked ( ch : u8 ) -> Self {
404
+ pub const unsafe fn from_ascii_unchecked ( ch : u8 ) -> Self {
379
405
// SAFETY: Caller guarantees `ch` is within bounds of ascii.
380
- unsafe { ch . to_ascii_char_unchecked ( ) }
406
+ unsafe { mem :: transmute ( ch ) }
381
407
}
382
408
383
409
/// Converts an ASCII character into a `u8`.
@@ -411,7 +437,7 @@ impl AsciiChar {
411
437
#[ inline]
412
438
#[ must_use]
413
439
pub const fn is_alphabetic ( self ) -> bool {
414
- ( self . to_not_upper ( ) >= b'a' ) & ( self . to_not_upper ( ) <= b'z' )
440
+ ( self . to_not_upper ( ) >= b'a' ) && ( self . to_not_upper ( ) <= b'z' )
415
441
}
416
442
417
443
/// Check if the character is a letter (a-z, A-Z).
@@ -457,14 +483,14 @@ impl AsciiChar {
457
483
#[ inline]
458
484
#[ must_use]
459
485
pub const fn is_ascii_digit ( & self ) -> bool {
460
- ( * self as u8 >= b'0' ) & ( * self as u8 <= b'9' )
486
+ ( * self as u8 >= b'0' ) && ( * self as u8 <= b'9' )
461
487
}
462
488
463
489
/// Check if the character is a letter or number
464
490
#[ inline]
465
491
#[ must_use]
466
492
pub const fn is_alphanumeric ( self ) -> bool {
467
- self . is_alphabetic ( ) | self . is_ascii_digit ( )
493
+ self . is_alphabetic ( ) || self . is_ascii_digit ( )
468
494
}
469
495
470
496
/// Check if the character is a letter or number
@@ -491,7 +517,7 @@ impl AsciiChar {
491
517
#[ inline]
492
518
#[ must_use]
493
519
pub const fn is_ascii_blank ( & self ) -> bool {
494
- ( * self as u8 == b' ' ) | ( * self as u8 == b'\t' )
520
+ ( * self as u8 == b' ' ) || ( * self as u8 == b'\t' )
495
521
}
496
522
497
523
/// Check if the character one of ' ', '\t', '\n', '\r',
@@ -500,7 +526,7 @@ impl AsciiChar {
500
526
#[ must_use]
501
527
pub const fn is_whitespace ( self ) -> bool {
502
528
let b = self as u8 ;
503
- self . is_ascii_blank ( ) | ( b == b'\n' ) | ( b == b'\r' ) | ( b == 0x0b ) | ( b == 0x0c )
529
+ self . is_ascii_blank ( ) || ( b == b'\n' ) || ( b == b'\r' ) || ( b == 0x0b ) | | ( b == 0x0c )
504
530
}
505
531
506
532
/// Check if the character is a ' ', '\t', '\n', '\r' or '\0xc' (form feed).
@@ -510,9 +536,9 @@ impl AsciiChar {
510
536
#[ must_use]
511
537
pub const fn is_ascii_whitespace ( & self ) -> bool {
512
538
self . is_ascii_blank ( )
513
- | ( * self as u8 == b'\n' )
514
- | ( * self as u8 == b'\r' )
515
- | ( * self as u8 == 0x0c /*form feed*/ )
539
+ || ( * self as u8 == b'\n' )
540
+ || ( * self as u8 == b'\r' )
541
+ || ( * self as u8 == 0x0c /*form feed*/ )
516
542
}
517
543
518
544
/// Check if the character is a control character
@@ -530,7 +556,7 @@ impl AsciiChar {
530
556
#[ inline]
531
557
#[ must_use]
532
558
pub const fn is_ascii_control ( & self ) -> bool {
533
- ( ( * self as u8 ) < b' ' ) | ( * self as u8 == 127 )
559
+ ( ( * self as u8 ) < b' ' ) || ( * self as u8 == 127 )
534
560
}
535
561
536
562
/// Checks if the character is printable (except space)
@@ -624,7 +650,7 @@ impl AsciiChar {
624
650
#[ inline]
625
651
#[ must_use]
626
652
pub const fn is_ascii_punctuation ( & self ) -> bool {
627
- self . is_ascii_graphic ( ) & !self . is_alphanumeric ( )
653
+ self . is_ascii_graphic ( ) && !self . is_alphanumeric ( )
628
654
}
629
655
630
656
/// Checks if the character is a valid hex digit
@@ -641,7 +667,7 @@ impl AsciiChar {
641
667
#[ inline]
642
668
#[ must_use]
643
669
pub const fn is_ascii_hexdigit ( & self ) -> bool {
644
- self . is_ascii_digit ( ) | ( ( * self as u8 | 0x20_u8 ) . wrapping_sub ( b'a' ) < 6 )
670
+ self . is_ascii_digit ( ) || ( ( * self as u8 | 0x20u8 ) . wrapping_sub ( b'a' ) < 6 )
645
671
}
646
672
647
673
/// Unicode has printable versions of the ASCII control codes, like '␛'.
@@ -659,14 +685,15 @@ impl AsciiChar {
659
685
/// assert_eq!(AsciiChar::new('p').as_printable_char(), 'p');
660
686
/// ```
661
687
#[ must_use]
662
- pub fn as_printable_char ( self ) -> char {
688
+ pub const fn as_printable_char ( self ) -> char {
689
+ #![ allow( clippy:: transmute_int_to_char) ] // from_utf32_unchecked() is not const fn yet.
663
690
match self as u8 {
664
691
// Non printable characters
665
692
// SAFETY: From codepoint 0x2400 ('␀') to 0x241f (`␟`), there are characters representing
666
693
// the unprintable characters from 0x0 to 0x1f, ordered correctly.
667
694
// As `b` is guaranteed to be within 0x0 to 0x1f, the conversion represents a
668
695
// valid character.
669
- b @ 0x0 ..=0x1f => unsafe { char :: from_u32_unchecked ( u32 :: from ( '␀' ) + u32:: from ( b ) ) } ,
696
+ b @ 0x0 ..=0x1f => unsafe { mem :: transmute ( '␀' as u32 + b as u32 ) } ,
670
697
671
698
// 0x7f (delete) has it's own character at codepoint 0x2420, not 0x247f, so it is special
672
699
// cased to return it's character
@@ -728,7 +755,7 @@ impl AsciiChar {
728
755
#[ must_use]
729
756
pub const fn eq_ignore_ascii_case ( & self , other : & Self ) -> bool {
730
757
( self . as_byte ( ) == other. as_byte ( ) )
731
- | ( self . is_alphabetic ( ) & ( self . to_not_upper ( ) == other. to_not_upper ( ) ) )
758
+ || ( self . is_alphabetic ( ) & & ( self . to_not_upper ( ) == other. to_not_upper ( ) ) )
732
759
}
733
760
}
734
761
0 commit comments