use std::error::Error;
use std::fmt;
use std::io::{self, Write};
use std::ops::{Deref, DerefMut};
use std::result;
use backend::Backend;
use sql_types::TypeMetadata;
#[cfg(feature = "postgres")]
pub use pg::serialize::*;
pub type Result = result::Result<IsNull, Box<dyn Error + Send + Sync>>;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum IsNull {
Yes,
No,
}
#[derive(Clone, Copy)]
pub struct Output<'a, T, DB>
where
DB: TypeMetadata,
DB::MetadataLookup: 'a,
{
out: T,
metadata_lookup: &'a DB::MetadataLookup,
}
impl<'a, T, DB: TypeMetadata> Output<'a, T, DB> {
pub fn new(out: T, metadata_lookup: &'a DB::MetadataLookup) -> Self {
Output {
out,
metadata_lookup,
}
}
pub fn with_buffer<U>(&self, new_out: U) -> Output<'a, U, DB> {
Output {
out: new_out,
metadata_lookup: self.metadata_lookup,
}
}
pub fn into_inner(self) -> T {
self.out
}
pub fn metadata_lookup(&self) -> &'a DB::MetadataLookup {
self.metadata_lookup
}
}
#[cfg(test)]
impl<DB: TypeMetadata> Output<'static, Vec<u8>, DB> {
pub fn test() -> Self {
use std::mem;
#[allow(clippy::invalid_ref)]
Self::new(Vec::new(), unsafe { mem::uninitialized() })
}
}
impl<'a, T: Write, DB: TypeMetadata> Write for Output<'a, T, DB> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.out.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.out.flush()
}
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.out.write_all(buf)
}
fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
self.out.write_fmt(fmt)
}
}
impl<'a, T, DB: TypeMetadata> Deref for Output<'a, T, DB> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.out
}
}
impl<'a, T, DB: TypeMetadata> DerefMut for Output<'a, T, DB> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.out
}
}
impl<'a, T, U, DB> PartialEq<U> for Output<'a, T, DB>
where
DB: TypeMetadata,
T: PartialEq<U>,
{
fn eq(&self, rhs: &U) -> bool {
self.out == *rhs
}
}
impl<'a, T, DB> fmt::Debug for Output<'a, T, DB>
where
T: fmt::Debug,
DB: TypeMetadata,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.out.fmt(f)
}
}
pub trait ToSql<A, DB: Backend>: fmt::Debug {
fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> Result;
}
impl<'a, A, T, DB> ToSql<A, DB> for &'a T
where
DB: Backend,
T: ToSql<A, DB> + ?Sized,
{
fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> Result {
(*self).to_sql(out)
}
}