Skip to main content

sqlx_mssql_odbc_macros/
lib.rs

1//! Proc-macros for the `sqlx-mssql-odbc` driver.
2//!
3//! This crate provides compile-time checked queries (`query!()`, `query_as!()`,
4//! `query_scalar!()`), derive macros (`Encode`, `Decode`, `Type`, `FromRow`),
5//! and optional migration support for MSSQL databases via ODBC.
6//!
7//! It is a thin wrapper around [`sqlx-macros-core`] that plugs in the MSSQL
8//! driver-specific types and `describe_blocking` implementation.
9
10use proc_macro::TokenStream;
11
12use quote::quote;
13
14use sqlx_macros_core as macros_core;
15
16// ---------------------------------------------------------------------------
17// Query macros
18// ---------------------------------------------------------------------------
19
20#[cfg(feature = "macros")]
21#[proc_macro]
22pub fn expand_query(input: TokenStream) -> TokenStream {
23    let input = syn::parse_macro_input!(input as macros_core::query::QueryMacroInput);
24
25    match macros_core::query::expand_input(
26        input,
27        &[sqlx_mssql_odbc_core::MSSQL_DRIVER],
28    ) {
29        Ok(ts) => ts.into(),
30        Err(e) => {
31            if let Some(parse_err) = e.downcast_ref::<syn::Error>() {
32                parse_err.to_compile_error().into()
33            } else {
34                let msg = e.to_string();
35                quote!(::std::compile_error!(#msg)).into()
36            }
37        }
38    }
39}
40
41// ---------------------------------------------------------------------------
42// Derive macros
43// ---------------------------------------------------------------------------
44
45#[cfg(feature = "derive")]
46#[proc_macro_derive(Encode, attributes(sqlx))]
47pub fn derive_encode(tokenstream: TokenStream) -> TokenStream {
48    let input = syn::parse_macro_input!(tokenstream as syn::DeriveInput);
49    match macros_core::derives::expand_derive_encode(&input) {
50        Ok(ts) => ts.into(),
51        Err(e) => e.to_compile_error().into(),
52    }
53}
54
55#[cfg(feature = "derive")]
56#[proc_macro_derive(Decode, attributes(sqlx))]
57pub fn derive_decode(tokenstream: TokenStream) -> TokenStream {
58    let input = syn::parse_macro_input!(tokenstream as syn::DeriveInput);
59    match macros_core::derives::expand_derive_decode(&input) {
60        Ok(ts) => ts.into(),
61        Err(e) => e.to_compile_error().into(),
62    }
63}
64
65#[cfg(feature = "derive")]
66#[proc_macro_derive(Type, attributes(sqlx))]
67pub fn derive_type(tokenstream: TokenStream) -> TokenStream {
68    let input = syn::parse_macro_input!(tokenstream as syn::DeriveInput);
69    match macros_core::derives::expand_derive_type_encode_decode(&input) {
70        Ok(ts) => ts.into(),
71        Err(e) => e.to_compile_error().into(),
72    }
73}
74
75#[cfg(feature = "derive")]
76#[proc_macro_derive(FromRow, attributes(sqlx))]
77pub fn derive_from_row(input: TokenStream) -> TokenStream {
78    let input = syn::parse_macro_input!(input as syn::DeriveInput);
79    match macros_core::derives::expand_derive_from_row(&input) {
80        Ok(ts) => ts.into(),
81        Err(e) => e.to_compile_error().into(),
82    }
83}
84
85// ---------------------------------------------------------------------------
86// Migrate macro (optional)
87// ---------------------------------------------------------------------------
88
89#[cfg(feature = "migrate")]
90#[proc_macro]
91pub fn migrate(input: TokenStream) -> TokenStream {
92    use syn::LitStr;
93
94    let input = syn::parse_macro_input!(input as Option<LitStr>);
95    match macros_core::migrate::expand(input) {
96        Ok(ts) => ts.into(),
97        Err(e) => {
98            if let Some(parse_err) = e.downcast_ref::<syn::Error>() {
99                parse_err.to_compile_error().into()
100            } else {
101                let msg = e.to_string();
102                quote!(::std::compile_error!(#msg)).into()
103            }
104        }
105    }
106}
107
108// ---------------------------------------------------------------------------
109// Test attribute (optional — requires macros feature in sqlx-macros-core)
110// ---------------------------------------------------------------------------
111
112#[cfg(feature = "macros")]
113#[proc_macro_attribute]
114pub fn test(args: TokenStream, input: TokenStream) -> TokenStream {
115    let input = syn::parse_macro_input!(input as syn::ItemFn);
116
117    match macros_core::test_attr::expand(args.into(), input) {
118        Ok(ts) => ts.into(),
119        Err(e) => {
120            if let Some(parse_err) = e.downcast_ref::<syn::Error>() {
121                parse_err.to_compile_error().into()
122            } else {
123                let msg = e.to_string();
124                quote!(::std::compile_error!(#msg)).into()
125            }
126        }
127    }
128}