ts_error/
lib.rs

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