except_plugin/core/
flex_impl.rs

1//! # flex impls for exceptions
2//! There are many traits to implement here, and when we implement a custom Exception
3//!
4//! these traits can provide standardized and flexible extension functions for the custom Exception
5//! ```txt
6//! @author:syf20020816@Outlook.com
7//! @date:2023/8/13
8//! @version:0.0.1
9//! @description:
10//! ```
11use std::collections::HashMap;
12use std::path::PathBuf;
13use std::time::{Duration};
14use super::{Exception, ExceptionLevel, Exceptions, Reasons};
15
16
17/// # New or From Exception
18/// Use this trait to create an Exception
19/// ## example
20/// ```rust
21/// impl NewFrom for SuperException {
22///     type Builder = SuperBuilder;
23///
24///     fn new() -> Self::Builder {
25///         SuperBuilder::new()
26///     }
27///     fn from(e: Box<dyn Exception>) -> Self where Self: Sized {
28///         SuperException {
29///             code: e.code(),
30///             msg: String::from(e.msg()),
31///             level: e.level(),
32///         }
33///     }
34/// }
35/// ```
36pub trait NewFrom {
37    type Builder;
38    /// create a new Exception
39    fn new() -> Self::Builder;
40    /// create a new Exception from any Exception
41    /// - can convert from : supper
42    fn from_super(e: Box<dyn Exception>) -> Self where Self: Sized;
43}
44
45/// # deref the exception
46/// convert &mut self to Self
47/// - impl each exception
48/// ## example
49/// ```rust
50/// impl DerefException for SuperException {
51///     fn deref_mut_exception(&mut self) -> Self {
52///         SuperException {
53///             code: self.code(),
54///             msg: String::from(self.msg()),
55///             level: self.level(),
56///         }
57///     }
58/// }
59pub trait DerefException {
60    fn deref_mut_exception(&mut self) -> Self;
61}
62
63/// # convert builder to exception
64/// ## example
65/// ```rust
66/// impl FromBuilder for SuperException {
67///     type Output = SuperException;
68///     type Input = SuperBuilder;
69///     fn from_builder(builder: &Self::Input) -> Self::Output {
70///         Self::Output {
71///             code: builder.code(),
72///             msg: String::from(builder.msg()),
73///             level: builder.level(),
74///         }
75///     }
76/// }
77/// ```
78pub trait FromBuilder {
79    /// builder type
80    type Input;
81    /// exception type
82    type Output;
83    fn from_builder(builder: &Self::Input) -> Self::Output;
84}
85
86pub trait SuperBuilderImpl<T> {
87    fn new() -> Self;
88    fn code(&self) -> u32;
89    fn msg(&self) -> &str;
90    fn level(&self) -> ExceptionLevel;
91    fn set_code(&mut self, code: u32) -> &mut Self;
92    fn set_msg(&mut self, msg: &str) -> &mut Self;
93    fn set_level(&mut self, level: ExceptionLevel) -> &mut Self;
94    fn exception_type(&self) -> Exceptions;
95    fn timestamp(&self) -> Duration;
96    fn build(&mut self) -> T;
97}
98
99pub trait CommonParamImpl {
100    fn line(&self) -> u32;
101    fn path(&self) -> PathBuf;
102    fn set_line(&mut self, line: u32) -> &mut Self;
103    fn set_path(&mut self, path: PathBuf) -> &mut Self;
104}
105
106pub trait TargetParamImpl {
107    fn target(&self) -> &str;
108    fn set_target(&mut self, target: &str) -> &mut Self;
109}
110
111pub trait OutOfBoundsParamImpl {
112    fn len(&self) -> usize;
113    fn set_len(&mut self, len: usize) -> &mut Self;
114    fn index(&self) -> usize;
115    fn set_index(&mut self, index: usize) -> &mut Self;
116}
117
118pub trait ReasonParamImpl {
119    fn reason(&self) -> Reasons;
120    fn set_reason(&mut self, reason: Reasons) -> &mut Self;
121}
122
123pub trait SQLParamImpl {
124    fn stmt(&self) -> &str;
125    fn set_stmt(&mut self, stmt: &str) -> &mut Self;
126    fn tips(&self) -> &HashMap<String, String>;
127    fn add_tip(&mut self, k: &str, v: &str) -> &mut Self;
128    fn set_tips(&mut self, tips: HashMap<String, String>) -> &mut Self;
129}
130
131//------------------------------------------------------------
132
133//------------------------------------------------------------
134/// # generate SuperBuilderImpl for each Builder
135/// it will generate implementations for each builder
136/// ## example
137/// ```rust
138/// use crate::builder_impl;
139///
140/// builder_impl!(SuperBuilder,SuperException);
141/// ```
142#[macro_export]
143macro_rules! builder_impl {
144    ($Builder:tt,$Output:tt) => {
145        impl SuperBuilderImpl<$Output> for $Builder {
146
147            fn new() -> Self {
148                Default::default()
149            }
150
151            fn code(&self) -> u32 {
152                self.code
153            }
154
155            fn msg(&self) -> &str {
156                &self.msg
157            }
158
159            fn level(&self) -> ExceptionLevel {
160                self.level.clone()
161            }
162
163            fn set_code(&mut self, code: u32) -> &mut Self {
164                self.code = code;
165                self
166            }
167
168            fn set_msg(&mut self, msg: &str) -> &mut Self {
169                self.msg = String::from(msg);
170                self
171            }
172
173            fn set_level(&mut self, level: ExceptionLevel) -> &mut Self {
174                self.level = level;
175                self
176            }
177            fn exception_type(&self) -> Exceptions {
178                self.e_type.clone()
179            }
180            fn timestamp(&self)->Duration{
181                self.timestamp
182            }
183            fn build(&mut self) -> $Output {
184                $Output::from_builder(self.deref())
185            }
186        }
187    };
188}
189
190/// generate display and error for all exceptions
191#[macro_export]
192macro_rules! display_err_impl {
193    ($E:tt) => {
194        impl Error for $E {
195            fn description(&self) -> &str {
196                self.msg()
197            }
198        }
199
200        impl Display for $E {
201            fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
202                Display::fmt(&self, f)
203            }
204        }
205    };
206}
207
208/// generate impl Exception for each Exception
209#[macro_export]
210macro_rules! exception_impl {
211    ($E:tt,$EType:expr) => {
212        impl Exception for $E {
213            fn code(&self) -> u32 {
214                self.code
215            }
216            fn msg(&self) -> &str {
217                &self.msg
218            }
219            fn level(&self) -> ExceptionLevel {
220                self.level.clone()
221            }
222            fn set_code(&mut self, code: u32) -> () {
223                self.code = code;
224            }
225            fn set_level(&mut self, level: ExceptionLevel) -> () {
226                self.level = level;
227            }
228            fn set_msg(&mut self, msg: &str) -> () {
229                self.msg = String::from(msg);
230            }
231            fn get_type(&self) -> Exceptions {
232                $EType
233            }
234            fn timestamp(&self)->Duration{
235                self.timestamp
236            }
237        }
238    };
239}
240
241/// # Generate NewFrom impl for specific exception
242#[macro_export]
243macro_rules! e_new_from_impl {
244    ($E:tt,$Builder:tt) => {
245        impl NewFrom for $E {
246            type Builder = $Builder;
247
248            fn new() -> Self::Builder {
249                $Builder::new()
250            }
251            fn from(e: Box<dyn Exception>) -> Self where Self: Sized {
252                $E {
253                    code: e.code(),
254                    msg: String::from(e.msg()),
255                    level: e.level(),
256                    line: e.line(),
257                    path: e.path(),
258                }
259            }
260        }
261    };
262}
263
264#[macro_export]
265macro_rules! common_param_impl {
266    ($E:tt) => {
267        impl CommonParamImpl for $E {
268            fn line(&self) -> u32 {
269                self.line
270            }
271            fn path(&self) -> PathBuf {
272                self.path.clone()
273            }
274            fn set_path(&mut self, path: PathBuf) -> &mut Self {
275                self.path = path;
276                self
277            }
278            fn set_line(&mut self, line: u32) -> &mut Self {
279                self.line = line;
280                self
281            }
282        }
283    };
284}
285
286/// # macro for TargetParamImpl
287#[macro_export]
288macro_rules! target_param_impl {
289    ($E:tt) => {
290        impl TargetParamImpl for $E {
291            fn target(&self) -> &str {
292                match self.target {
293                    Some(ref s) => s.as_str(),
294                    None => ""
295                }
296            }
297            fn set_target(&mut self, target: &str) -> &mut Self {
298                self.target = Some(target.to_string());
299                self
300            }
301        }
302    };
303}
304
305/// # macro for OutOfBoundsImpl
306#[macro_export]
307macro_rules! out_of_bounds_impl {
308    ($E:tt) => {
309        impl OutOfBoundsParamImpl for $E{
310            fn len(&self) -> usize {
311                self.len
312            }
313            fn set_len(&mut self, len: usize) -> &mut Self {
314                self.len = len;
315                self
316            }
317            fn index(&self) -> usize {
318                self.index
319            }
320            fn set_index(&mut self, index: usize) -> &mut Self {
321                self.index = index;
322                self
323            }
324        }
325    };
326}
327
328#[macro_export]
329macro_rules! reason_param_impl {
330    ($E:tt) => {
331        impl ReasonParamImpl for $E {
332            fn reason(&self) -> Reasons {
333                self.reason.clone()
334            }
335            fn set_reason(&mut self, reason: Reasons) -> &mut Self {
336                self.reason = reason;
337                self
338            }
339        }
340    };
341}
342
343#[macro_export]
344macro_rules! sql_param_impl {
345    ($E:tt) => {
346        impl SQLParamImpl for $E {
347            fn stmt(&self) -> &str {
348                match self.stmt {
349                    Some(ref s) => s.as_str(),
350                    None => ""
351                }
352            }
353            fn set_stmt(&mut self, stmt: &str) -> &mut Self {
354                self.stmt = Some(stmt.to_string());
355                self
356            }
357            fn tips(&self) -> &HashMap<String, String> {
358                &self.tips
359            }
360            fn set_tips(&mut self,tips: HashMap<String, String>) -> &mut Self {
361                self.tips = tips;
362                self
363            }
364            fn add_tip(&mut self, k: &str, v: &str) -> &mut Self {
365                self.tips.insert(String::from(k), String::from(v));
366                self
367            }
368        }
369    };
370}