ascii_cli/
info.rs

1use std::collections::HashMap;
2
3use colored::Colorize;
4use radix_fmt::radix;
5
6use crate::{table, verification};
7
8pub fn what_is(string: Option<String>, base: u8, is_special: bool) {
9    verification::check_base(base);
10
11    let string = match string {
12        Some(n) => n,
13        None => verification::get_input("Char to inspect"),
14    };
15
16    let mut special = is_special;
17
18    let character;
19    let name;
20    let mut description = String::new();
21    let mut category = String::new();
22
23    let mut number = 0;
24
25    if special {
26        character = string.to_uppercase();
27    } else {
28        let num = verification::get_number(string.clone(), base);
29        verification::under_128(num);
30        number = num;
31        if let Some(special_char) = table::get_special_chars().get(&num) {
32            character = special_char.to_owned();
33            special = true;
34        } else {
35            character = char::from_u32(num).unwrap().to_string();
36        }
37    }
38
39    if special {
40        if let Some(char_set) = get_special_descriptions().get(&character.as_str()) {
41            name = format!("{} - {}", character, char_set.0);
42            description = char_set.1.to_owned();
43            number = char_set.2 as u32;
44            category = "Control Character".to_owned();
45        } else {
46            println!(
47                "{}",
48                format!("\"{}\" is not a Control Character!", character)
49                    .red()
50                    .bold()
51            );
52            std::process::exit(1);
53        }
54    } else {
55        if (32..=47).contains(&number)
56            || (58..=64).contains(&number)
57            || (91..=96).contains(&number)
58            || (123..=126).contains(&number)
59        {
60            category = "Special Characters".to_owned();
61            description = "A special character, typically used for punctuations".to_owned();
62        } else if (30..=39).contains(&number) {
63            category = "Numbers".to_owned();
64            description = "A number in base 10 (0-9)".to_owned();
65        } else if (65..=90).contains(&number) {
66            category = "Uppercase letter".to_owned();
67            description = "An Uppercase letter in the english alphabet (A-Z)".to_owned();
68        } else if (97..=122).contains(&number) {
69            category = "Lowercase letter".to_owned();
70            description = "A lowercase letter in the english alphabet (a-z)".to_owned();
71        }
72        name = character;
73    }
74
75    println!(
76        "{}",
77        format!("{}: {}", radix(number, base), name).blue().bold()
78    );
79    println!("{} {}", "Category:".blue().bold(), category.italic());
80    println!("{} {}", "Description:".blue().bold(), description.italic());
81}
82
83fn get_special_descriptions() -> HashMap<&'static str, (&'static str, &'static str, u8)> {
84    HashMap::from([
85        ("NUL", ("NULL character", "The null character prompts the device to do nothing", 0)),
86        ("SOH", ("Start Of Heading", "Initiates a header", 1)),
87        ("STX", ("Start Of Text", "Ends the header and marks the beginning of a message", 2)),
88        ("ETX", ("End Of Text", "Indicates the end of the message", 3)),
89        ("EOT", ("End Of Transmission", "Marks the end of a completes transmission", 4)),
90        ("ENQ", ("Enquiry", "A request that requires a response", 5)),
91        ("ACK", ("Acknowledge", "Gives a positive answer to the request", 6)),
92        ("BEL", ("Bell", "Triggers a beep", 7)),
93        ("BS", ("Backspace", "Lets the cursor move back one step", 8)),
94        ("HT", ("Horizontal tab", "A horizontal tab that moves the cursor within a row to the next predefined position", 9)),
95        ("LF", ("Line Feed", "Causes the cursor to jump to the next line", 10)),
96        ("VT", ("Vertical Tab", "The vertical tab lets the cursor jump to a predefined line", 11)),
97        ("FF", ("Form Feed", "Requests a page break", 12)),
98        ("CR", ("Carriage Return", "Moves the cursor back to the first position of the line", 13)),
99        ("SO", ("Shift Out", "Switches to a special presentation", 14)),
100        ("SI", ("Shift In", "Switches the display back to the normal state", 15)),
101        ("DLE", ("Data Link Escape", "Changes the meaning of the following characters", 16)),
102        ("DC1", ("Device Control", "Control characters assigned depending on the device used", 17)),
103        ("DC2", ("Device Control", "Control characters assigned depending on the device used", 18)),
104        ("DC3", ("Device Control", "Control characters assigned depending on the device used", 19)),
105        ("DC4", ("Device Control", "Control characters assigned depending on the device used", 20)),
106        ("NAK", ("Negative Acknowledge", "Negative response to a request", 21)),
107        ("SYN", ("Synchronous Idle", "Synchronizes a data transfer, even if no signals are transmitted", 22)),
108        ("ETB", ("End of Transmission Block", "Marks the end of a transmission block", 23)),
109        ("CAN", ("Cancel", "Makes it clear that a transmission was faulty and the data must be discarded", 24)),
110        ("EM", ("End of Medium", "Indicates the end of the storage medium", 25)),
111        ("SUB", ("Substitute", "Replacement for a faulty sign", 26)),
112        ("ESC", ("Escape", "Initiates an escape sequence and thus gives the following characters a special meaning", 27)),
113        ("FS", ("File Separator", "Marks the separation of logical data blocks and is hierarchically ordered: file as the largest unit, file as the smallest unit", 28)),
114        ("GS", ("Group Separator", "Marks the separation of logical data blocks and is hierarchically ordered: file as the largest unit, file as the smallest unit", 29)),
115        ("RS", ("Record Separator", "Marks the separation of logical data blocks and is hierarchically ordered: file as the largest unit, file as the smallest unit", 30)),
116        ("US", ("Unit Separator", "Marks the separation of logical data blocks and is hierarchically ordered: file as the largest unit, file as the smallest unit", 31)),
117        ("DEL", ("Delete", "Deletes a character. Since this control character consists of the same number on all positions, during the typewriter era it was possible to invalidate another character by punching out all the positions", 127)),
118    ])
119}