use time::OffsetDateTime;
use uuid::Uuid;
pub trait SqlxBindable: std::fmt::Debug {
fn bind_query<'q>(
&'q self,
query: sqlx::query::Query<'q, sqlx::Postgres, sqlx::postgres::PgArguments>,
) -> sqlx::query::Query<'q, sqlx::Postgres, sqlx::postgres::PgArguments>;
fn raw(&self) -> Option<&str> {
None
}
}
#[macro_export]
macro_rules! bindable {
($($t:ty),*) => {
$(impl $crate::SqlxBindable for $t {
fn bind_query<'q>(&self, query: sqlx::query::Query<'q, sqlx::Postgres, sqlx::postgres::PgArguments>) -> sqlx::query::Query<'q, sqlx::Postgres, sqlx::postgres::PgArguments> {
let query = query.bind(self.clone());
query
}
}
impl $crate::SqlxBindable for &$t {
fn bind_query<'q>(&self, query: sqlx::query::Query<'q, sqlx::Postgres, sqlx::postgres::PgArguments>) -> sqlx::query::Query<'q, sqlx::Postgres, sqlx::postgres::PgArguments> {
let query = query.bind(<$t>::clone(self));
query
}
}
)*
};
}
#[macro_export]
macro_rules! bindable_to_string {
($($t:ident),*) => {
$(
impl $crate::SqlxBindable for $t {
fn bind_query<'q>(&self, query: sqlx::query::Query<'q, sqlx::Postgres, sqlx::postgres::PgArguments>) -> sqlx::query::Query<'q, sqlx::Postgres, sqlx::postgres::PgArguments> {
let query = query.bind(self.to_string());
query
}
}
impl $crate::SqlxBindable for &$t {
fn bind_query<'q>(&self, query: sqlx::query::Query<'q, sqlx::Postgres, sqlx::postgres::PgArguments>) -> sqlx::query::Query<'q, sqlx::Postgres, sqlx::postgres::PgArguments> {
let query = query.bind(self.to_string());
query
}
}
)*
};
}
bindable_to_string!(String, str);
impl<T> SqlxBindable for Option<T>
where
T: SqlxBindable + Clone + Send,
T: for<'r> sqlx::Encode<'r, sqlx::Postgres>,
T: sqlx::Type<sqlx::Postgres>,
{
fn bind_query<'q>(
&'q self,
query: sqlx::query::Query<'q, sqlx::Postgres, sqlx::postgres::PgArguments>,
) -> sqlx::query::Query<'q, sqlx::Postgres, sqlx::postgres::PgArguments> {
let query = query.bind(self.clone());
query
}
}
bindable!(bool);
bindable!(i8, i16, i32, i64, f32, f64);
bindable!(Uuid, OffsetDateTime);
#[cfg(feature = "chrono-support")]
mod chrono_support {
use chrono::{NaiveDateTime, NaiveDate, NaiveTime, DateTime, Utc};
bindable!(NaiveDateTime, NaiveDate, NaiveTime, DateTime<Utc>);
}
#[derive(Debug)]
pub struct Raw(pub &'static str);
impl SqlxBindable for Raw {
fn bind_query<'q>(
&self,
query: sqlx::query::Query<'q, sqlx::Postgres, sqlx::postgres::PgArguments>,
) -> sqlx::query::Query<'q, sqlx::Postgres, sqlx::postgres::PgArguments> {
query
}
fn raw(&self) -> Option<&str> {
Some(self.0)
}
}
#[cfg(test)]
mod tests {
use crate::Field;
#[test]
fn field_from_str() {
let field = Field::from(("name1", "v2"));
assert_eq!("name1", field.name);
let field: Field = ("name1", "v2").into();
assert_eq!("name1", field.name);
}
#[test]
fn field_from_string() {
let field = Field::from(("name1", "v1"));
assert_eq!("name1", field.name);
let v2 = &"v2".to_string();
let field: Field = ("name2", v2).into();
assert_eq!("name2", field.name);
}
}