from_sqlite_row_macro/
lib.rs1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{DeriveInput, parse_macro_input, Fields, Type};
4
5#[proc_macro_derive(FromSqliteRow)]
9pub fn derive_from_sqlite_row(input: TokenStream) -> TokenStream {
10 let input = parse_macro_input!(input as DeriveInput);
12 let name = input.ident; let fields = match input.data {
16 syn::Data::Struct(s) => s.fields,
17 _ => panic!("FromSqliteRow 只能用于结构体"),
18 };
19
20 let field_initializers = match fields {
22 Fields::Named(fields) => {
23 let field_names = fields.named.clone();
24 field_names.into_iter().map(|field| {
25 let ident = field.ident.as_ref().unwrap();
27 let ident_str = ident.to_string();
29 let field_type = &field.ty;
31
32 let field_get_code = if let Type::Path(path) = field_type {
33 if let Some(seg) = path.path.segments.last() {
35 if seg.ident == "String" {
36 quote! { row.read::<&str, _>(#ident_str).to_string() }
38 } else {
39 quote! { row.read(#ident_str) }
41 }
42 } else {
43 quote! { row.read(#ident_str) }
44 }
45 } else {
46 quote! { row.read(#ident_str) }
47 };
48
49 quote! {
51 #ident: #field_get_code
52 }
53 })
54 },
55 _ => panic!("FromSqliteRow 只支持带命名字段的结构体"),
56 };
57
58 let expanded = quote! {
60 impl FromSqliteRow for #name {
61 fn from_row(row: &sqlite::Row) -> Self {
62 Self {
63 #(#field_initializers),*
64 }
65 }
66 }
67 };
68
69 TokenStream::from(expanded)
70}