1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
#![cfg_attr(rustfmt, rustfmt_skip)] use ascii_char::{AsciiChar, ToAsciiChar}; // I would like to require C: AsciiExt, but it's not in core. /// Terminals use [caret notation](https://en.wikipedia.org/wiki/Caret_notation) /// to display some typed control codes, such as ^D for EOT and ^Z for SUB. /// /// This function returns the caret notation letter for control codes, /// or `None` for printable characters. /// /// # Examples /// ``` /// # use ascii::{AsciiChar, caret_encode}; /// assert_eq!(caret_encode(b'\0'), Some(AsciiChar::At)); /// assert_eq!(caret_encode(AsciiChar::DEL), Some(AsciiChar::Question)); /// assert_eq!(caret_encode(b'E'), None); /// assert_eq!(caret_encode(b'\n'), Some(AsciiChar::J)); /// ``` pub fn caret_encode<C: Copy + Into<u8>>(c: C) -> Option<AsciiChar> { // The formula is explained in the Wikipedia article. let c = c.into() ^ 0b0100_0000; unsafe { if c >= b'?' && c <= b'_' { Some(c.to_ascii_char_unchecked()) } else { None } } } /// Returns the control code represented by a [caret notation](https://en.wikipedia.org/wiki/Caret_notation) /// letter, or `None` if the letter is not used in caret notation. /// /// This function is the inverse of `caret_encode()`. /// /// # Examples /// /// Basic usage: /// /// ``` /// # use ascii::{AsciiChar, caret_decode}; /// assert_eq!(caret_decode(b'?'), Some(AsciiChar::DEL)); /// assert_eq!(caret_decode(AsciiChar::D), Some(AsciiChar::EOT)); /// assert_eq!(caret_decode(b'\0'), None); /// ``` /// /// Symmetry: /// /// ``` /// # use ascii::{AsciiChar, caret_encode, caret_decode}; /// assert_eq!(caret_encode(AsciiChar::US).and_then(caret_decode), Some(AsciiChar::US)); /// assert_eq!(caret_decode(b'@').and_then(caret_encode), Some(AsciiChar::At)); /// ``` pub fn caret_decode<C: Copy + Into<u8>>(c: C) -> Option<AsciiChar> { // The formula is explained in the Wikipedia article. unsafe { match c.into() { b'?'...b'_' => Some(AsciiChar::from_unchecked(c.into() ^ 0b0100_0000)), _ => None, } } }