sqlx_core/
column.rs

1use crate::database::Database;
2use crate::error::Error;
3
4use std::fmt::Debug;
5
6pub trait Column: 'static + Send + Sync + Debug {
7    type Database: Database<Column = Self>;
8
9    /// Gets the column ordinal.
10    ///
11    /// This can be used to unambiguously refer to this column within a row in case more than
12    /// one column have the same name
13    fn ordinal(&self) -> usize;
14
15    /// Gets the column name or alias.
16    ///
17    /// The column name is unreliable (and can change between database minor versions) if this
18    /// column is an expression that has not been aliased.
19    fn name(&self) -> &str;
20
21    /// Gets the type information for the column.
22    fn type_info(&self) -> &<Self::Database as Database>::TypeInfo;
23}
24
25/// A type that can be used to index into a [`Row`] or [`Statement`].
26///
27/// The [`get`] and [`try_get`] methods of [`Row`] accept any type that implements `ColumnIndex`.
28/// This trait is implemented for strings which are used to look up a column by name, and for
29/// `usize` which is used as a positional index into the row.
30///
31/// [`Row`]: crate::row::Row
32/// [`Statement`]: crate::statement::Statement
33/// [`get`]: crate::row::Row::get
34/// [`try_get`]: crate::row::Row::try_get
35///
36pub trait ColumnIndex<T: ?Sized>: Debug {
37    /// Returns a valid positional index into the row or statement, [`ColumnIndexOutOfBounds`], or,
38    /// [`ColumnNotFound`].
39    ///
40    /// [`ColumnNotFound`]: Error::ColumnNotFound
41    /// [`ColumnIndexOutOfBounds`]: Error::ColumnIndexOutOfBounds
42    fn index(&self, container: &T) -> Result<usize, Error>;
43}
44
45impl<T: ?Sized, I: ColumnIndex<T> + ?Sized> ColumnIndex<T> for &'_ I {
46    #[inline]
47    fn index(&self, row: &T) -> Result<usize, Error> {
48        (**self).index(row)
49    }
50}
51
52#[macro_export]
53macro_rules! impl_column_index_for_row {
54    ($R:ident) => {
55        impl $crate::column::ColumnIndex<$R> for usize {
56            fn index(&self, row: &$R) -> Result<usize, $crate::error::Error> {
57                let len = $crate::row::Row::len(row);
58
59                if *self >= len {
60                    return Err($crate::error::Error::ColumnIndexOutOfBounds { len, index: *self });
61                }
62
63                Ok(*self)
64            }
65        }
66    };
67}
68
69#[macro_export]
70macro_rules! impl_column_index_for_statement {
71    ($S:ident) => {
72        impl $crate::column::ColumnIndex<$S<'_>> for usize {
73            fn index(&self, statement: &$S<'_>) -> Result<usize, $crate::error::Error> {
74                let len = $crate::statement::Statement::columns(statement).len();
75
76                if *self >= len {
77                    return Err($crate::error::Error::ColumnIndexOutOfBounds { len, index: *self });
78                }
79
80                Ok(*self)
81            }
82        }
83    };
84}