mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-25 02:21:37 +08:00
Fix macro hygiene issue
This commit is contained in:
parent
0e369ba878
commit
f0670ccadd
@ -1,6 +1,6 @@
|
|||||||
//! Private implementation details of `rusqlite`.
|
//! Private implementation details of `rusqlite`.
|
||||||
|
|
||||||
use proc_macro::{Delimiter, Literal, TokenStream, TokenTree};
|
use proc_macro::{Delimiter, Group, Literal, Span, TokenStream, TokenTree};
|
||||||
|
|
||||||
use fallible_iterator::FallibleIterator;
|
use fallible_iterator::FallibleIterator;
|
||||||
use sqlite3_parser::ast::{ParameterInfo, ToTokens};
|
use sqlite3_parser::ast::{ParameterInfo, ToTokens};
|
||||||
@ -58,15 +58,19 @@ fn try_bind(input: TokenStream) -> Result<TokenStream> {
|
|||||||
return Err("Mixing named and numbered parameters is not supported.".to_string());
|
return Err("Mixing named and numbered parameters is not supported.".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let call_site = literal.span();
|
||||||
let mut res = TokenStream::new();
|
let mut res = TokenStream::new();
|
||||||
for (i, name) in info.names.iter().enumerate() {
|
for (i, name) in info.names.iter().enumerate() {
|
||||||
//eprintln!("(i: {}, name: {})", i + 1, &name[1..]);
|
//eprintln!("(i: {}, name: {})", i + 1, &name[1..]);
|
||||||
res.extend(Some(stmt.clone()));
|
res.extend(Some(stmt.clone()));
|
||||||
res.extend(parse_ts(&format!(
|
res.extend(respan(
|
||||||
".raw_bind_parameter({}, &{})?;",
|
parse_ts(&format!(
|
||||||
i + 1,
|
".raw_bind_parameter({}, &{})?;",
|
||||||
&name[1..]
|
i + 1,
|
||||||
)));
|
&name[1..]
|
||||||
|
)),
|
||||||
|
call_site,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
@ -93,6 +97,24 @@ fn strip_matches<'a>(s: &'a str, pattern: &str) -> &'a str {
|
|||||||
.unwrap_or(s)
|
.unwrap_or(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn respan(ts: TokenStream, span: Span) -> TokenStream {
|
||||||
|
let mut res = TokenStream::new();
|
||||||
|
for tt in ts {
|
||||||
|
let tt = match tt {
|
||||||
|
TokenTree::Ident(mut ident) => {
|
||||||
|
ident.set_span(ident.span().resolved_at(span).located_at(span));
|
||||||
|
TokenTree::Ident(ident)
|
||||||
|
}
|
||||||
|
TokenTree::Group(group) => {
|
||||||
|
TokenTree::Group(Group::new(group.delimiter(), respan(group.stream(), span)))
|
||||||
|
}
|
||||||
|
_ => tt,
|
||||||
|
};
|
||||||
|
res.extend(Some(tt))
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_ts(s: &str) -> TokenStream {
|
fn parse_ts(s: &str) -> TokenStream {
|
||||||
s.parse().unwrap()
|
s.parse().unwrap()
|
||||||
}
|
}
|
||||||
|
25
src/lib.rs
25
src/lib.rs
@ -215,11 +215,26 @@ macro_rules! named_params {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Captured identifiers in SQL
|
/// Captured identifiers in SQL
|
||||||
|
///
|
||||||
|
/// * only SQLite `$x` / `@x` / `:x` syntax works (Rust `&x` syntax does not
|
||||||
|
/// work).
|
||||||
|
/// * `$x.y` expression does not work.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust, no_run
|
||||||
|
/// # use rusqlite::{prepare_and_bind, Connection, Result, Statement};
|
||||||
|
///
|
||||||
|
/// fn misc(db: &Connection) -> Result<Statement> {
|
||||||
|
/// let name = "Lisa";
|
||||||
|
/// let age = 8;
|
||||||
|
/// let smart = true;
|
||||||
|
/// Ok(prepare_and_bind!(db, "SELECT $name, @age, :smart;"))
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! prepare_and_bind {
|
macro_rules! prepare_and_bind {
|
||||||
($conn:expr, $sql:literal) => {{
|
($conn:expr, $sql:literal) => {{
|
||||||
#[cfg(trick_rust_analyzer_into_highlighting_interpolated_bits)]
|
|
||||||
format_args!($sql);
|
|
||||||
let mut stmt = $conn.prepare($sql)?;
|
let mut stmt = $conn.prepare($sql)?;
|
||||||
$crate::__bind!(stmt $sql);
|
$crate::__bind!(stmt $sql);
|
||||||
stmt
|
stmt
|
||||||
@ -227,11 +242,13 @@ macro_rules! prepare_and_bind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Captured identifiers in SQL
|
/// Captured identifiers in SQL
|
||||||
|
///
|
||||||
|
/// * only SQLite `$x` / `@x` / `:x` syntax works (Rust `&x` syntax does not
|
||||||
|
/// work).
|
||||||
|
/// * `$x.y` expression does not work.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! prepare_cached_and_bind {
|
macro_rules! prepare_cached_and_bind {
|
||||||
($conn:expr, $sql:literal) => {{
|
($conn:expr, $sql:literal) => {{
|
||||||
#[cfg(trick_rust_analyzer_into_highlighting_interpolated_bits)]
|
|
||||||
format_args!($sql);
|
|
||||||
let mut stmt = $conn.prepare_cached($sql)?;
|
let mut stmt = $conn.prepare_cached($sql)?;
|
||||||
$crate::__bind!(stmt $sql);
|
$crate::__bind!(stmt $sql);
|
||||||
stmt
|
stmt
|
||||||
|
Loading…
Reference in New Issue
Block a user