use crate::database::Database; use crate::error::Error; use std::fmt::Debug; pub trait Column: private_column::Sealed + 'static + Send + Sync + Debug { type Database: Database; /// Gets the column ordinal. /// /// This can be used to unambiguously refer to this column within a row in case more than /// one column have the same name fn ordinal(&self) -> usize; /// Gets the column name or alias. /// /// The column name is unreliable (and can change between database minor versions) if this /// column is an expression that has not been aliased. fn name(&self) -> &str; /// Gets the type information for the column. fn type_info(&self) -> &::TypeInfo; } // Prevent users from implementing the `Row` trait. pub(crate) mod private_column { pub trait Sealed {} } /// A type that can be used to index into a [`Row`] or [`Statement`]. /// /// The [`get`] and [`try_get`] methods of [`Row`] accept any type that implements `ColumnIndex`. /// This trait is implemented for strings which are used to look up a column by name, and for /// `usize` which is used as a positional index into the row. /// /// This trait is sealed and cannot be implemented for types outside of SQLx. /// /// [`Row`]: crate::row::Row /// [`Statement`]: crate::statement::Statement /// [`get`]: crate::row::Row::get /// [`try_get`]: crate::row::Row::try_get /// pub trait ColumnIndex: private_column_index::Sealed + Debug { /// Returns a valid positional index into the row or statement, [`ColumnIndexOutOfBounds`], or, /// [`ColumnNotFound`]. /// /// [`ColumnNotFound`]: ../enum.Error.html#variant.ColumnNotFound /// [`ColumnIndexOutOfBounds`]: ../enum.Error.html#variant.ColumnIndexOutOfBounds fn index(&self, container: &T) -> Result; } impl + ?Sized> ColumnIndex for &'_ I { #[inline] fn index(&self, row: &T) -> Result { (**self).index(row) } } macro_rules! impl_column_index_for_row { ($R:ident) => { impl crate::column::ColumnIndex<$R> for usize { fn index(&self, row: &$R) -> Result { let len = crate::row::Row::len(row); if *self >= len { return Err(crate::error::Error::ColumnIndexOutOfBounds { len, index: *self }); } Ok(*self) } } }; } macro_rules! impl_column_index_for_statement { ($S:ident) => { impl crate::column::ColumnIndex<$S<'_>> for usize { fn index(&self, statement: &$S<'_>) -> Result { let len = crate::statement::Statement::columns(statement).len(); if *self >= len { return Err(crate::error::Error::ColumnIndexOutOfBounds { len, index: *self }); } Ok(*self) } } }; } // Prevent users from implementing the `ColumnIndex` trait. mod private_column_index { pub trait Sealed {} impl Sealed for usize {} impl Sealed for str {} impl Sealed for &'_ T where T: Sealed + ?Sized {} }