Skip to main content

grp_core/error/
structs.rs

1use std::fmt::Display;
2
3use color_print::cformat;
4
5use crate::error::tools::Notes;
6
7/// # Error
8/// This is the _error struct_ used in all the lib 
9/// it implements some based functionality to show the error 
10/// in a beautifull format.
11/// 
12/// There are to basic ways to create a new error, 
13/// with a preset and additional information, or a custom, for 
14/// your own error.
15/// 
16/// ## Example 1
17/// ~~~
18/// use grp_core::{ErrorType, Error};
19/// 
20/// Error::new(
21///     ErrorType::ResponseParsing,
22///     vec!["description", "{}"]
23/// );
24/// ~~~
25/// 
26/// Error contains a vector to emulate various parameter to allow a more 
27/// usefull message to the user. In this case, the `ErrorType::ResponseParsing` 
28/// needs at least 2 parameters, one for the description of the error, 
29/// and other for the text that generates the error.
30/// 
31/// ## Example 2
32/// ~~~
33/// use grp_core::{ErrorType, Error};
34/// 
35/// Error::new_custom(
36///     "Custom error message",
37///     vec!["something whent wrong after...", "don't be afraid"] // here, every item is trated as a new line (if printed)
38/// );
39/// ~~~
40/// 
41/// You also can create custom errors using the _build in_ method _new_custom_ 
42/// this is usefull if you whant to canvert between error in your aplication, 
43/// a good example is present in _https://github.com/feraxhp/grp_, where the 
44/// errors from git2 are parsed to grp_core errors, in order to keep the 
45/// same error throughout all the aplication. 
46/// 
47/// ## Example 3
48/// ~~~
49/// use grp_core::{ErrorType, Error};
50/// 
51/// let normal_error = Error::new(
52///     ErrorType::ResponseParsing,
53///     vec!["description", "{}"]
54/// );
55/// 
56/// let error_custom = Error::new_custom(
57///     "Custom error message",
58///     vec!["something whent wrong after...", "don't be afraid"] // here, every item is trated as a new line (if printed)
59/// );
60/// 
61/// let collection_error = Error::colection(vec![normal_error, error_custom]);
62/// ~~~
63/// 
64/// There is a 3 type and is a collection, this allows to return multiple errors 
65/// in just one `grp_core::Error`. usefull for paggination errors, or concations of multiple 
66/// of them.
67#[derive(Debug, Clone)]
68pub struct Error {
69    pub(super) etype: String,
70    pub message: String,
71    pub content: Vec<String>,
72}
73
74#[allow(dead_code)]
75impl Error {
76    pub fn new<P, K, M>(
77        etype: &'static str, 
78        message: M,
79        detail: P,
80        explanation: Vec<String>,
81        notes: Vec<K>,
82    ) -> Error
83    where 
84        P: Display,
85        M: Display,
86        K: Display,
87    {
88        let notes_legth = notes.len();
89        let mut content: Vec<String> = Vec::with_capacity(notes_legth + 1 + explanation.len());
90        
91        content.push(cformat!("<y>* {}</>", detail));
92        content.extend(explanation);
93        
94        if notes_legth > 0 { 
95            content.push(cformat!(""));
96            content.push(cformat!("<g># notes</>"));
97            content.extend(notes.iter().as_notes());
98        }
99        
100        Error { 
101            etype: format!("custom::{}", etype), 
102            message: message.to_string(), 
103            content
104        }
105    }
106    
107    pub fn collection(errors: Vec<Error>) -> Error {
108        let mut content = Vec::new();
109        for error in errors {
110            content.push(cformat!("\n*<r>{}</>",error.message));
111            content.extend(error.content.iter().map(|s| format!("  {}", s)));
112        }
113        Error { 
114            etype: "".to_string(),
115            message: "Multiple errors found".to_string(),
116            content: content
117        }
118    }
119    
120    pub fn get_type(&self) -> String { self.etype.to_owned() }
121    
122    pub fn show(&self) { self.show_with_offset(0); }
123    pub fn show_with_offset(&self, offset: usize) {
124        self.content.iter().for_each(|line| {
125            eprintln!("{:width$}{}", "", line, width = offset);
126        });
127    }
128}