ts_error/
lib.rs

1//! # `ts-error`
2//!
3//! Traits for convenient error reporting, and error report/stack creation
4
5#![no_std]
6
7extern crate alloc;
8#[cfg(feature = "std")]
9extern crate std;
10
11pub mod diagnostic;
12mod logger;
13mod program_exit;
14mod report;
15
16use alloc::string::{String, ToString};
17
18pub use logger::LogError;
19pub use program_exit::{ProgramReport, ReportProgramExit};
20pub use report::Report;
21
22#[cfg(feature = "std")]
23pub use logger::StderrError;
24
25/// Normalize an error message.
26/// * Starts with lowercase character unless followed by an uppercase character.
27/// * Does not end with any punctuation.
28pub fn normalize_message<S: ToString>(message: S) -> String {
29    let message = message.to_string();
30    let message = message.trim();
31    let mut output = String::with_capacity(message.len());
32
33    let mut chars = message.chars();
34    let first_char = chars.next();
35    let second_char = chars.next();
36
37    // Handle acronyms
38    if let Some(first_char) = first_char
39        && let Some(second_char) = second_char
40        && first_char.is_uppercase()
41        && !second_char.is_uppercase()
42    {
43        output.push(first_char.to_ascii_lowercase());
44        output.push(second_char);
45    } else {
46        if let Some(first_char) = first_char {
47            output.push(first_char);
48        }
49        if let Some(second_char) = second_char {
50            output.push(second_char);
51        }
52    }
53
54    let mut chars = chars.rev().peekable();
55    // Skip trailing punctuation
56    while chars.next_if(char::is_ascii_punctuation).is_some() {}
57
58    output.push_str(&chars.rev().collect::<String>());
59
60    output.trim().to_string()
61}
62
63#[cfg(test)]
64mod test {
65    use crate::normalize_message;
66
67    #[test]
68    fn does_not_normalize_acronyms() {
69        let message = "JSON";
70        assert_eq!(message, normalize_message(message));
71
72        let message = "  JSON  ";
73        assert_eq!("JSON", normalize_message(message));
74    }
75
76    #[test]
77    fn normalizes_sentences() {
78        let message = "Whether";
79        assert_eq!("whether", normalize_message(message));
80
81        let message = "  Whether  ";
82        assert_eq!("whether", normalize_message(message));
83    }
84
85    #[test]
86    fn removes_punctuation() {
87        let message = "message.,;/";
88        assert_eq!("message", normalize_message(message));
89
90        let message = "  message .,;/  ";
91        assert_eq!("message", normalize_message(message));
92    }
93}