From 3470195839b6c432fc697602478e36b630da7650 Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Mon, 22 Feb 2021 21:22:04 -0800 Subject: [PATCH] feat(core): add ColumnIndex --- sqlx-core/src/lib.rs | 2 +- sqlx-core/src/row.rs | 43 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/sqlx-core/src/lib.rs b/sqlx-core/src/lib.rs index f3f8bd99..e121e3b3 100644 --- a/sqlx-core/src/lib.rs +++ b/sqlx-core/src/lib.rs @@ -70,7 +70,7 @@ pub use isolation_level::IsolationLevel; pub use options::ConnectOptions; pub use query_result::QueryResult; pub use r#type::{Type, TypeDecode, TypeEncode}; -pub use row::Row; +pub use row::{ColumnIndex, Row}; #[cfg(feature = "actix")] pub use runtime::Actix; #[cfg(feature = "async")] diff --git a/sqlx-core/src/row.rs b/sqlx-core/src/row.rs index 902f5398..c9dae54b 100644 --- a/sqlx-core/src/row.rs +++ b/sqlx-core/src/row.rs @@ -1,6 +1,7 @@ use crate::database::HasRawValue; use crate::{Database, Decode}; +/// A single row from a result set generated from the database. pub trait Row: 'static + Send + Sync { type Database: Database; @@ -31,18 +32,48 @@ pub trait Row: 'static + Send + Sync { fn try_ordinal_of(&self, name: &str) -> crate::Result; /// Returns the decoded value at the index. - fn try_get<'r, T>(&'r self, index: usize) -> crate::Result + fn try_get<'r, T, I>(&'r self, index: I) -> crate::Result where + I: ColumnIndex, T: Decode<'r, Self::Database>; /// Returns the raw representation of the value at the index. #[allow(clippy::needless_lifetimes)] - fn try_get_raw<'r>( + fn try_get_raw<'r, I: ColumnIndex>( &'r self, - index: usize, + index: I, ) -> crate::Result<>::RawValue>; } -// TODO: fn type_info_of(index) -// TODO: fn try_type_info_of(index) -// TODO: trait ColumnIndex +/// A helper trait used for indexing into a [`Row`]. +pub trait ColumnIndex { + /// Returns the ordinal of the column at this index, if present. + #[allow(clippy::needless_lifetimes)] + fn get<'r>(&self, row: &'r R) -> crate::Result; +} + +// access an ordinal by index +impl ColumnIndex for usize { + #[allow(clippy::needless_lifetimes)] + fn get<'r>(&self, _row: &'r R) -> crate::Result { + // note: the "index out of bounds" error will be surfaced + // by [try_get] + Ok(*self) + } +} + +// access an ordinal by name +impl ColumnIndex for &'_ str { + #[allow(clippy::needless_lifetimes)] + fn get<'r>(&self, row: &'r R) -> crate::Result { + row.try_ordinal_of(self) + } +} + +// access by reference +impl> ColumnIndex for &'_ I { + #[allow(clippy::needless_lifetimes)] + fn get<'r>(&self, row: &'r R) -> crate::Result { + (*self).get(row) + } +}