use crate::error::Result;
use crate::types::Oid;
use bytes::BytesMut;
pub trait ToSql {
fn oid(&self) -> Oid;
fn to_sql(&self, buf: &mut BytesMut) -> Result<()>;
fn to_sql_vec(&self) -> Result<Vec<u8>> {
let mut buf = BytesMut::new();
self.to_sql(&mut buf)?;
Ok(buf.to_vec())
}
fn is_null(&self) -> bool {
false
}
}
pub trait FromSql: Sized {
fn oid() -> Oid;
fn from_sql(buf: &[u8]) -> Result<Self>;
fn from_sql_nullable(buf: Option<&[u8]>) -> Result<Self> {
match buf {
Some(b) => Self::from_sql(b),
None => Err(crate::error::Error::Decode(
"unexpected NULL value".to_string(),
)),
}
}
}
impl<T: FromSql> FromSql for Option<T> {
fn oid() -> Oid {
T::oid()
}
fn from_sql(buf: &[u8]) -> Result<Self> {
T::from_sql(buf).map(Some)
}
fn from_sql_nullable(buf: Option<&[u8]>) -> Result<Self> {
match buf {
Some(b) => T::from_sql(b).map(Some),
None => Ok(None),
}
}
}
impl<T: ToSql> ToSql for Option<T> {
fn oid(&self) -> Oid {
match self {
Some(v) => v.oid(),
None => Oid::TEXT,
}
}
fn to_sql(&self, buf: &mut BytesMut) -> Result<()> {
match self {
Some(v) => v.to_sql(buf),
None => Ok(()), }
}
fn is_null(&self) -> bool {
self.is_none()
}
}
pub fn encode_param<T: ToSql>(val: &T) -> Result<Vec<u8>> {
val.to_sql_vec()
}
pub fn encode_param_nullable<T: ToSql>(val: &Option<T>) -> Result<Option<Vec<u8>>> {
match val {
Some(v) => Ok(Some(v.to_sql_vec()?)),
None => Ok(None),
}
}