mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
48 lines
1.6 KiB
Rust
48 lines
1.6 KiB
Rust
#![recursion_limit = "128"]
|
|
extern crate proc_macro;
|
|
|
|
use crate::proc_macro::TokenStream;
|
|
use quote::quote;
|
|
|
|
// For now, assume (not check) that these macroses are applied to enum without
|
|
// data. If this assumption is violated, compiler error will point to
|
|
// generated code, which is not very user-friendly.
|
|
|
|
#[proc_macro_derive(ToSql)]
|
|
pub fn to_sql_derive(input: TokenStream) -> TokenStream {
|
|
let ast: syn::DeriveInput = syn::parse(input).unwrap();
|
|
let name = &ast.ident;
|
|
|
|
let gen = quote! {
|
|
impl rusqlite::types::ToSql for #name {
|
|
fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput> {
|
|
let num = *self as i64;
|
|
let value = rusqlite::types::Value::Integer(num);
|
|
let output = rusqlite::types::ToSqlOutput::Owned(value);
|
|
std::result::Result::Ok(output)
|
|
}
|
|
}
|
|
};
|
|
gen.into()
|
|
}
|
|
|
|
#[proc_macro_derive(FromSql)]
|
|
pub fn from_sql_derive(input: TokenStream) -> TokenStream {
|
|
let ast: syn::DeriveInput = syn::parse(input).unwrap();
|
|
let name = &ast.ident;
|
|
|
|
let gen = quote! {
|
|
impl rusqlite::types::FromSql for #name {
|
|
fn column_result(col: rusqlite::types::ValueRef) -> rusqlite::types::FromSqlResult<Self> {
|
|
let inner = rusqlite::types::FromSql::column_result(col)?;
|
|
if let Some(value) = num_traits::FromPrimitive::from_i64(inner) {
|
|
Ok(value)
|
|
} else {
|
|
Err(rusqlite::types::FromSqlError::OutOfRange(inner))
|
|
}
|
|
}
|
|
}
|
|
};
|
|
gen.into()
|
|
}
|