Redo FromSql

Still use from_sql_nullable internally to preserve back compat, but
implementation should use from_sql_null instead
This commit is contained in:
Steven Fackler 2015-10-24 19:24:00 -07:00
parent 78818f9fb0
commit 5d047683f0

View File

@ -593,21 +593,12 @@ impl error::Error for WasNull {
/// `Option<T>` where `T` implements `FromSql`. An `Option<T>` represents a /// `Option<T>` where `T` implements `FromSql`. An `Option<T>` represents a
/// nullable Postgres value. /// nullable Postgres value.
pub trait FromSql: Sized { pub trait FromSql: Sized {
/// Creates a new value of this type from a `Read`er of Postgres data. /// ### Deprecated
///
/// If the value was `NULL`, the `Read`er will be `None`.
///
/// The caller of this method is responsible for ensuring that this type
/// is compatible with the Postgres `Type`.
///
/// The default implementation calls `FromSql::from_sql` when `raw` is
/// `Some` and returns `Err(Error::Conversion(Box::new(WasNull))` when
/// `raw` is `None`. It does not typically need to be overridden.
fn from_sql_nullable<R: Read>(ty: &Type, raw: Option<&mut R>, ctx: &SessionInfo) fn from_sql_nullable<R: Read>(ty: &Type, raw: Option<&mut R>, ctx: &SessionInfo)
-> Result<Self> { -> Result<Self> {
match raw { match raw {
Some(raw) => FromSql::from_sql(ty, raw, ctx), Some(raw) => FromSql::from_sql(ty, raw, ctx),
None => Err(Error::Conversion(Box::new(WasNull))), None => FromSql::from_sql_null(ty, ctx),
} }
} }
@ -618,24 +609,31 @@ pub trait FromSql: Sized {
/// is compatible with the Postgres `Type`. /// is compatible with the Postgres `Type`.
fn from_sql<R: Read>(ty: &Type, raw: &mut R, ctx: &SessionInfo) -> Result<Self>; fn from_sql<R: Read>(ty: &Type, raw: &mut R, ctx: &SessionInfo) -> Result<Self>;
/// Creates a new value of this type from a `NULL` SQL value.
///
/// The caller of this method is responsible for ensuring that this type
/// is compatible with the Postgres `Type`.
///
/// The default implementation returns
/// `Err(Error::Conversion(Box::new(WasNull))`.
fn from_sql_null(ty: &Type, ctx: &SessionInfo) -> Result<Self> {
Err(Error::Conversion(Box::new(WasNull)))
}
/// Determines if a value of this type can be created from the specified /// Determines if a value of this type can be created from the specified
/// Postgres `Type`. /// Postgres `Type`.
fn accepts(ty: &Type) -> bool; fn accepts(ty: &Type) -> bool;
} }
impl<T: FromSql> FromSql for Option<T> { impl<T: FromSql> FromSql for Option<T> {
fn from_sql_nullable<R: Read>(ty: &Type, raw: Option<&mut R>, ctx: &SessionInfo)
-> Result<Option<T>> {
match raw {
Some(raw) => <T as FromSql>::from_sql(ty, raw, ctx).map(Some),
None => Ok(None),
}
}
fn from_sql<R: Read>(ty: &Type, raw: &mut R, ctx: &SessionInfo) -> Result<Option<T>> { fn from_sql<R: Read>(ty: &Type, raw: &mut R, ctx: &SessionInfo) -> Result<Option<T>> {
<T as FromSql>::from_sql(ty, raw, ctx).map(Some) <T as FromSql>::from_sql(ty, raw, ctx).map(Some)
} }
fn from_sql_null(_: &Type, _: &SessionInfo) -> Result<Option<T>> {
Ok(None)
}
fn accepts(ty: &Type) -> bool { fn accepts(ty: &Type) -> bool {
<T as FromSql>::accepts(ty) <T as FromSql>::accepts(ty)
} }