tds_driver_macros/lib.rs
1//! A utility proc-macro crate that generates trivial trait implementations used
2//! in the Rust-to-SQL data exchange for tds-driver table-valued parameters.
3extern crate proc_macro;
4
5#[macro_use]
6extern crate quote;
7#[macro_use]
8extern crate syn;
9
10use proc_macro::TokenStream;
11
12macro_rules! sp_quote {
13 ($($t:tt)*) => (quote_spanned!(proc_macro2::Span::call_site() => $($t)*))
14}
15
16mod attr;
17mod table_value_param;
18
19/// Generates a trivial implementation of the `TableValueRow` trait.
20///
21/// # Applications
22/// Apply to structs that represent rows of a table-valued parameter.
23///
24/// # Example
25/// ```rust,ignore
26/// # use tds_driver::*;
27/// #[derive(TableValueRow)]
28/// pub struct SomeGeoList {
29/// #[colname = "SomeID"]
30/// pub id: i32,
31/// #[colname = "LastSyncIPGeoLat"]
32/// pub lat: Numeric,
33/// #[colname = "LastSyncIPGeoLong"]
34/// pub lon: Numeric,
35/// }
36/// ```
37///
38/// # Supported field types
39///
40/// Each field is bound with `SqlTableDataRow::add_field(self.<field>)`, so the
41/// field type must implement `IntoSql` *by value*. That covers the `Copy`
42/// scalar/marker types (`i32`, `i64`, `bool`, `f64`, `Numeric`, `Uuid`, …) and
43/// borrowed strings/bytes (`&str`, `&[u8]`). Owned, non-`Copy` columns such as
44/// `String` or `Vec<u8>` cannot be moved out of `&self`; model those columns as
45/// `&str` / `&[u8]` (with a struct lifetime) instead.
46#[proc_macro_derive(TableValueRow, attributes(colname))]
47pub fn table_value_param(input: TokenStream) -> TokenStream {
48 let ast: syn::DeriveInput = match syn::parse(input) {
49 Ok(ast) => ast,
50 Err(e) => return e.to_compile_error().into(),
51 };
52
53 let result = match ast.data {
54 syn::Data::Struct(ref s) => table_value_param::for_struct(&ast, &s.fields),
55 syn::Data::Enum(_) => Err(syn::Error::new_spanned(
56 &ast.ident,
57 "TableValueRow can only be derived for structs, not enums",
58 )),
59 syn::Data::Union(_) => Err(syn::Error::new_spanned(
60 &ast.ident,
61 "TableValueRow can only be derived for structs, not unions",
62 )),
63 };
64
65 match result {
66 Ok(tokens) => tokens.into(),
67 Err(e) => e.to_compile_error().into(),
68 }
69}