pub trait SqlQuote<OUT>
where OUT:std::fmt::Display
{
fn sql_quote(&self)->OUT;
}
macro_rules! sql_quote_self {
($in_type:ty) => {
impl SqlQuote<$in_type> for $in_type{
fn sql_quote(&self)->$in_type{*self}
}
};
}
macro_rules! sql_quote_vec {
($in_type:ty) => {
impl SqlQuote<String> for $in_type
{
fn sql_quote(&self)->String{
self.into_iter().map(|e|{
format!("{}",e.sql_quote())
}).collect::<Vec<String>>()
.join(",")
}
}
};
}
sql_quote_self!(i8);
sql_quote_self!(i16);
sql_quote_self!(i32);
sql_quote_self!(i64);
sql_quote_self!(i128);
sql_quote_self!(u8);
sql_quote_self!(u16);
sql_quote_self!(u32);
sql_quote_self!(u64);
sql_quote_self!(u128);
sql_quote_self!(f32);
sql_quote_self!(f64);
sql_quote_self!(usize);
sql_quote_self!(isize);
sql_quote_vec!(Vec<i8>);
sql_quote_vec!(Vec<i16>);
sql_quote_vec!(Vec<i32>);
sql_quote_vec!(Vec<i64>);
sql_quote_vec!(Vec<i128>);
sql_quote_vec!(Vec<u8>);
sql_quote_vec!(Vec<u16>);
sql_quote_vec!(Vec<u32>);
sql_quote_vec!(Vec<u64>);
sql_quote_vec!(Vec<u128>);
sql_quote_vec!(Vec<f32>);
sql_quote_vec!(Vec<f64>);
sql_quote_vec!(Vec<usize>);
sql_quote_vec!(Vec<isize>);
impl SqlQuote<String> for char{
fn sql_quote(&self)->String{
if (*self)=='\'' {
"'\\''".to_string()
} else {
format!("'{}'",self)
}
}
}
impl SqlQuote<u8> for bool{
fn sql_quote(&self)->u8{
(*self) as u8
}
}
impl SqlQuote<String> for &str{
fn sql_quote(&self)->String{
format!("'{}'",self.replace("'", "\\'"))
}
}
impl SqlQuote<String> for String{
fn sql_quote(&self)->String{
format!("'{}'",self.replace("'", "\\'"))
}
}
sql_quote_vec!(Vec<bool>);
sql_quote_vec!(Vec<&str>);
sql_quote_vec!(Vec<String>);
sql_quote_vec!([i8]);
sql_quote_vec!([i16]);
sql_quote_vec!([i32]);
sql_quote_vec!([i64]);
sql_quote_vec!([i128]);
sql_quote_vec!([u8]);
sql_quote_vec!([u16]);
sql_quote_vec!([u32]);
sql_quote_vec!([u64]);
sql_quote_vec!([u128]);
sql_quote_vec!([f32]);
sql_quote_vec!([f64]);
sql_quote_vec!([usize]);
sql_quote_vec!([isize]);
sql_quote_vec!([bool]);
sql_quote_vec!([String]);
sql_quote_vec!([&str]);
#[macro_export]
macro_rules! sql_format {
($fmt:expr) => {
format!($fmt)
};
($fmt:expr,$($args:tt),+$(,)?) => {
format!($fmt,$(
$args.sql_quote()
) ,+)
};
($fmt:expr,$($argsname:tt=$argsval:tt),+$(,)?) => {
format!($fmt,$(
$argsname=$argsval.sql_quote()
) ,+)
};
}
#[test]
fn test_sql_val(){
let str_val1="1";
let str_val2="1'1'1";
let char_val1='\'';
let char_val2='"';
let i_val1=1;
let ivac=vec![1,2,4];
let evac:Vec<String>=vec![];
let str_vac=vec!["1","1'1","2'2'2'2'"];
let str_arr=["1","1'1","2'2'2'2'"];
let str_arr1=["1".to_string(),"1'1".to_string(),"2'2'2'2'".to_string()];
let sql=sql_format!(
"select
{str_val1} as s1,
{str_val2} as s2,
{char_val1} as s3,
{char_val2} as s4,
{i_val1} as s5,
({ivac}) as s6,
({evac}) as s7,
({str_vac}) as s8,
({str_arr}) as s9,
({str_arr1}) as s10
",
str_val1=str_val1,
str_val2=str_val2,
char_val1=char_val1,
char_val2=char_val2,
i_val1=i_val1,
ivac=ivac,
evac=evac,
str_vac=str_vac,
str_arr=str_arr,
str_arr1=str_arr1
);
assert!(!sql.is_empty());
}