@@ -360,6 +360,32 @@ impl AsciiChar {
360360 ALL [ ch as usize ]
361361 }
362362
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+
363389 /// Constructs an ASCII character from a `u8`, `char` or other character
364390 /// type without any checks.
365391 ///
@@ -375,9 +401,9 @@ impl AsciiChar {
375401 /// and `Some(AsciiChar::from_ascii_unchecked(128))` might be `None`.
376402 #[ inline]
377403 #[ must_use]
378- pub unsafe fn from_ascii_unchecked ( ch : u8 ) -> Self {
404+ pub const unsafe fn from_ascii_unchecked ( ch : u8 ) -> Self {
379405 // SAFETY: Caller guarantees `ch` is within bounds of ascii.
380- unsafe { ch . to_ascii_char_unchecked ( ) }
406+ unsafe { mem :: transmute ( ch ) }
381407 }
382408
383409 /// Converts an ASCII character into a `u8`.
@@ -411,7 +437,7 @@ impl AsciiChar {
411437 #[ inline]
412438 #[ must_use]
413439 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' )
415441 }
416442
417443 /// Check if the character is a letter (a-z, A-Z).
@@ -457,14 +483,14 @@ impl AsciiChar {
457483 #[ inline]
458484 #[ must_use]
459485 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' )
461487 }
462488
463489 /// Check if the character is a letter or number
464490 #[ inline]
465491 #[ must_use]
466492 pub const fn is_alphanumeric ( self ) -> bool {
467- self . is_alphabetic ( ) | self . is_ascii_digit ( )
493+ self . is_alphabetic ( ) || self . is_ascii_digit ( )
468494 }
469495
470496 /// Check if the character is a letter or number
@@ -491,7 +517,7 @@ impl AsciiChar {
491517 #[ inline]
492518 #[ must_use]
493519 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' )
495521 }
496522
497523 /// Check if the character one of ' ', '\t', '\n', '\r',
@@ -500,7 +526,7 @@ impl AsciiChar {
500526 #[ must_use]
501527 pub const fn is_whitespace ( self ) -> bool {
502528 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 )
504530 }
505531
506532 /// Check if the character is a ' ', '\t', '\n', '\r' or '\0xc' (form feed).
@@ -510,9 +536,9 @@ impl AsciiChar {
510536 #[ must_use]
511537 pub const fn is_ascii_whitespace ( & self ) -> bool {
512538 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*/ )
516542 }
517543
518544 /// Check if the character is a control character
@@ -530,7 +556,7 @@ impl AsciiChar {
530556 #[ inline]
531557 #[ must_use]
532558 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 )
534560 }
535561
536562 /// Checks if the character is printable (except space)
@@ -624,7 +650,7 @@ impl AsciiChar {
624650 #[ inline]
625651 #[ must_use]
626652 pub const fn is_ascii_punctuation ( & self ) -> bool {
627- self . is_ascii_graphic ( ) & !self . is_alphanumeric ( )
653+ self . is_ascii_graphic ( ) && !self . is_alphanumeric ( )
628654 }
629655
630656 /// Checks if the character is a valid hex digit
@@ -641,7 +667,7 @@ impl AsciiChar {
641667 #[ inline]
642668 #[ must_use]
643669 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 )
645671 }
646672
647673 /// Unicode has printable versions of the ASCII control codes, like '␛'.
@@ -659,14 +685,15 @@ impl AsciiChar {
659685 /// assert_eq!(AsciiChar::new('p').as_printable_char(), 'p');
660686 /// ```
661687 #[ 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.
663690 match self as u8 {
664691 // Non printable characters
665692 // SAFETY: From codepoint 0x2400 ('␀') to 0x241f (`␟`), there are characters representing
666693 // the unprintable characters from 0x0 to 0x1f, ordered correctly.
667694 // As `b` is guaranteed to be within 0x0 to 0x1f, the conversion represents a
668695 // 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 ) } ,
670697
671698 // 0x7f (delete) has it's own character at codepoint 0x2420, not 0x247f, so it is special
672699 // cased to return it's character
@@ -728,7 +755,7 @@ impl AsciiChar {
728755 #[ must_use]
729756 pub const fn eq_ignore_ascii_case ( & self , other : & Self ) -> bool {
730757 ( 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 ( ) ) )
732759 }
733760}
734761
0 commit comments