mirror of
https://github.com/chatmail/core.git
synced 2026-09-22 13:01:21 +03:00
Largest change is in the FFI crate.
With 2024 (but not 2021) edition unsafe code
inside unsafe functions should be marked separately
so we can mark exactly the code that is unsafe.
Some CFFI functions even have no unsafe code inside.
Most interesting change is that .strdup()
functions are not marked as unsafe anymore.
They are allocating memory and return raw pointers,
but there is nothing unsafe about it.
Only using the returned raw pointers is unsafe.
This way calls to .strdup() don't have to be marked
with unsafe{} blocks.
49 lines
1.6 KiB
Rust
49 lines
1.6 KiB
Rust
#![recursion_limit = "128"]
|
|
extern crate proc_macro;
|
|
|
|
use quote::quote;
|
|
|
|
use crate::proc_macro::TokenStream;
|
|
|
|
// For now, assume (not check) that these macros 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 q = 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)
|
|
}
|
|
}
|
|
};
|
|
q.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 q = 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))
|
|
}
|
|
}
|
|
}
|
|
};
|
|
q.into()
|
|
}
|