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}