1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
pub use sqlx_core::{
    database::{Database, HasValueRef},
    decode::Decode,
    error::Error,
    type_info::TypeInfo as _,
    types::Type,
    value::ValueRef as _,
};

use crate::error::mismatched_types;

pub trait ValueRefTryGet<'r, DB, T>
where
    DB: Database,
    T: Decode<'r, DB> + Type<DB>,
{
    fn try_get(self) -> Result<T, Error>;
}

impl<'r, DB, T> ValueRefTryGet<'r, DB, T> for (<DB as HasValueRef<'r>>::ValueRef, usize)
where
    DB: Database,
    T: Decode<'r, DB> + Type<DB>,
{
    fn try_get(self) -> Result<T, Error> {
        let (value, index) = self;

        // https://github.com/launchbadge/sqlx/blob/v0.5.1/sqlx-core/src/row.rs#L111
        if !value.is_null() {
            let ty = value.type_info();

            if !ty.is_null() && !T::compatible(&ty) {
                return Err(Error::ColumnDecode {
                    index: format!("{index:?}"),
                    source: mismatched_types::<DB, T>(&ty),
                });
            }
        }

        T::decode(value).map_err(|source| Error::ColumnDecode {
            index: format!("{index:?}"),
            source,
        })
    }
}