use std::collections::HashMap;
use std::path::PathBuf;
use std::time::{Duration};
use super::{Exception, ExceptionLevel, Exceptions, Reasons};
pub trait NewFrom {
type Builder;
fn new() -> Self::Builder;
fn from_super(e: Box<dyn Exception>) -> Self where Self: Sized;
}
pub trait DerefException {
fn deref_mut_exception(&mut self) -> Self;
}
pub trait FromBuilder {
type Input;
type Output;
fn from_builder(builder: &Self::Input) -> Self::Output;
}
pub trait SuperBuilderImpl<T> {
fn new() -> Self;
fn code(&self) -> u32;
fn msg(&self) -> &str;
fn level(&self) -> ExceptionLevel;
fn set_code(&mut self, code: u32) -> &mut Self;
fn set_msg(&mut self, msg: &str) -> &mut Self;
fn set_level(&mut self, level: ExceptionLevel) -> &mut Self;
fn exception_type(&self) -> Exceptions;
fn timestamp(&self) -> Duration;
fn build(&mut self) -> T;
}
pub trait CommonParamImpl {
fn line(&self) -> u32;
fn path(&self) -> PathBuf;
fn set_line(&mut self, line: u32) -> &mut Self;
fn set_path(&mut self, path: PathBuf) -> &mut Self;
}
pub trait TargetParamImpl {
fn target(&self) -> &str;
fn set_target(&mut self, target: &str) -> &mut Self;
}
pub trait OutOfBoundsParamImpl {
fn len(&self) -> usize;
fn set_len(&mut self, len: usize) -> &mut Self;
fn index(&self) -> usize;
fn set_index(&mut self, index: usize) -> &mut Self;
}
pub trait ReasonParamImpl {
fn reason(&self) -> Reasons;
fn set_reason(&mut self, reason: Reasons) -> &mut Self;
}
pub trait SQLParamImpl {
fn stmt(&self) -> &str;
fn set_stmt(&mut self, stmt: &str) -> &mut Self;
fn tips(&self) -> &HashMap<String, String>;
fn add_tip(&mut self, k: &str, v: &str) -> &mut Self;
fn set_tips(&mut self, tips: HashMap<String, String>) -> &mut Self;
}
#[macro_export]
macro_rules! builder_impl {
($Builder:tt,$Output:tt) => {
impl SuperBuilderImpl<$Output> for $Builder {
fn new() -> Self {
Default::default()
}
fn code(&self) -> u32 {
self.code
}
fn msg(&self) -> &str {
&self.msg
}
fn level(&self) -> ExceptionLevel {
self.level.clone()
}
fn set_code(&mut self, code: u32) -> &mut Self {
self.code = code;
self
}
fn set_msg(&mut self, msg: &str) -> &mut Self {
self.msg = String::from(msg);
self
}
fn set_level(&mut self, level: ExceptionLevel) -> &mut Self {
self.level = level;
self
}
fn exception_type(&self) -> Exceptions {
self.e_type.clone()
}
fn timestamp(&self)->Duration{
self.timestamp
}
fn build(&mut self) -> $Output {
$Output::from_builder(self.deref())
}
}
};
}
#[macro_export]
macro_rules! display_err_impl {
($E:tt) => {
impl Error for $E {
fn description(&self) -> &str {
self.msg()
}
}
impl Display for $E {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Display::fmt(&self, f)
}
}
};
}
#[macro_export]
macro_rules! exception_impl {
($E:tt,$EType:expr) => {
impl Exception for $E {
fn code(&self) -> u32 {
self.code
}
fn msg(&self) -> &str {
&self.msg
}
fn level(&self) -> ExceptionLevel {
self.level.clone()
}
fn set_code(&mut self, code: u32) -> () {
self.code = code;
}
fn set_level(&mut self, level: ExceptionLevel) -> () {
self.level = level;
}
fn set_msg(&mut self, msg: &str) -> () {
self.msg = String::from(msg);
}
fn get_type(&self) -> Exceptions {
$EType
}
fn timestamp(&self)->Duration{
self.timestamp
}
}
};
}
#[macro_export]
macro_rules! e_new_from_impl {
($E:tt,$Builder:tt) => {
impl NewFrom for $E {
type Builder = $Builder;
fn new() -> Self::Builder {
$Builder::new()
}
fn from(e: Box<dyn Exception>) -> Self where Self: Sized {
$E {
code: e.code(),
msg: String::from(e.msg()),
level: e.level(),
line: e.line(),
path: e.path(),
}
}
}
};
}
#[macro_export]
macro_rules! common_param_impl {
($E:tt) => {
impl CommonParamImpl for $E {
fn line(&self) -> u32 {
self.line
}
fn path(&self) -> PathBuf {
self.path.clone()
}
fn set_path(&mut self, path: PathBuf) -> &mut Self {
self.path = path;
self
}
fn set_line(&mut self, line: u32) -> &mut Self {
self.line = line;
self
}
}
};
}
#[macro_export]
macro_rules! target_param_impl {
($E:tt) => {
impl TargetParamImpl for $E {
fn target(&self) -> &str {
match self.target {
Some(ref s) => s.as_str(),
None => ""
}
}
fn set_target(&mut self, target: &str) -> &mut Self {
self.target = Some(target.to_string());
self
}
}
};
}
#[macro_export]
macro_rules! out_of_bounds_impl {
($E:tt) => {
impl OutOfBoundsParamImpl for $E{
fn len(&self) -> usize {
self.len
}
fn set_len(&mut self, len: usize) -> &mut Self {
self.len = len;
self
}
fn index(&self) -> usize {
self.index
}
fn set_index(&mut self, index: usize) -> &mut Self {
self.index = index;
self
}
}
};
}
#[macro_export]
macro_rules! reason_param_impl {
($E:tt) => {
impl ReasonParamImpl for $E {
fn reason(&self) -> Reasons {
self.reason.clone()
}
fn set_reason(&mut self, reason: Reasons) -> &mut Self {
self.reason = reason;
self
}
}
};
}
#[macro_export]
macro_rules! sql_param_impl {
($E:tt) => {
impl SQLParamImpl for $E {
fn stmt(&self) -> &str {
match self.stmt {
Some(ref s) => s.as_str(),
None => ""
}
}
fn set_stmt(&mut self, stmt: &str) -> &mut Self {
self.stmt = Some(stmt.to_string());
self
}
fn tips(&self) -> &HashMap<String, String> {
&self.tips
}
fn set_tips(&mut self,tips: HashMap<String, String>) -> &mut Self {
self.tips = tips;
self
}
fn add_tip(&mut self, k: &str, v: &str) -> &mut Self {
self.tips.insert(String::from(k), String::from(v));
self
}
}
};
}