sqlx_conditional_queries_macros/
lib.rs1#![doc = include_str!("../README.md")]
2
3use proc_macro_error2::abort;
4use sqlx_conditional_queries_core::{AnalyzeError, DatabaseType, Error, ExpandError};
5
6const DATABASE_TYPE: DatabaseType = if cfg!(feature = "postgres") {
7 DatabaseType::PostgreSql
8} else if cfg!(feature = "mysql") {
9 DatabaseType::MySql
10} else if cfg!(feature = "sqlite") {
11 DatabaseType::Sqlite
12} else {
13 panic!("No database feature was enabled")
14};
15
16#[proc_macro_error2::proc_macro_error]
18#[proc_macro]
19pub fn conditional_query_as(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
20 conditional_query_as_inner(input, true)
21}
22
23#[proc_macro_error2::proc_macro_error]
25#[proc_macro]
26pub fn conditional_query_as_unchecked(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
27 conditional_query_as_inner(input, false)
28}
29
30fn conditional_query_as_inner(
31 input: proc_macro::TokenStream,
32 checked: bool,
33) -> proc_macro::TokenStream {
34 let input: proc_macro2::TokenStream = input.into();
35
36 let ts = match sqlx_conditional_queries_core::conditional_query_as(
37 DATABASE_TYPE,
38 input,
39 checked,
40 ) {
41 Ok(ts) => ts,
42 Err(Error::SynError(err)) => {
43 return err.to_compile_error().into();
44 }
45 Err(Error::AnalyzeError(err)) => match err {
46 AnalyzeError::ExpectedStringLiteral(span) => abort!(
47 span,
48 "expected string literal";
49 help = "only string literals or tuples of string literals are supported in compile-time bindings";
50 ),
51 AnalyzeError::BindingNameValueLengthMismatch {
52 names,
53 names_span,
54 values,
55 values_span,
56 } => abort!(
57 names_span,
58 "mismatch between number of names and values";
59 names = names_span => "number of names: {}", names;
60 values = values_span => "number of values: {}", values;
61 ),
62 AnalyzeError::DuplicatedCompileTimeBindingsFound { first: _, second } => {
63 abort!(second.span(), "found duplicate compile-time binding")
64 }
65 AnalyzeError::CompileTimeBindingCycleDetected { root_ident, path } => abort!(
66 root_ident.span(),
67 "detected compile-time binding cycle: {}",
68 path
69 ),
70 },
71 Err(Error::ExpandError(err)) => match err {
72 ExpandError::MissingCompileTimeBinding(binding, span) => abort!(
74 span,
75 "missing compile-time binding";
76 help = "found no compile-time binding with the specified name: {}", binding;
77 ),
78 ExpandError::MissingBindingClosingBrace(span) => abort!(
80 span,
81 "missing closing brace for compile-time binding reference"
82 ),
83 ExpandError::BindingReferenceTypeOverrideParseError(err, span) => abort!(
84 span,
85 "failed to parse type override in binding reference: {}",
86 err
87 ),
88 },
89 };
90
91 let output: proc_macro::TokenStream = ts.into();
92 output
93}