sqlite_tiny/api/
types.rs

1//! Bridge types to help with SQLite data types
2
3use crate::err;
4use crate::error::Error;
5use std::sync::Arc;
6
7/// An SQLite convertible type
8#[derive(Debug, Clone, PartialEq)]
9pub enum SqliteType {
10    /// NULL
11    Null,
12    /// INTEGER
13    Integer(i64),
14    /// REAL
15    Real(f64),
16    /// TEXT
17    Text(String),
18    /// BLOB
19    Blob(Vec<u8>),
20}
21
22// Byte array conversions
23impl<const LEN: usize> TryInto<[u8; LEN]> for SqliteType {
24    type Error = Error;
25
26    #[rustfmt::skip]
27    fn try_into(self) -> Result<[u8; LEN], Self::Error> {
28        match self {
29            SqliteType::Blob(value) => <[u8; LEN]>::try_from(value)
30                .map_err(|_| err!("Failed to convert from SQLite type")),
31            _ => Err(err!("Failed to convert from SQLite type")),
32        }
33    }
34}
35impl<const LEN: usize> TryInto<Option<[u8; LEN]>> for SqliteType {
36    type Error = Error;
37
38    #[rustfmt::skip]
39    fn try_into(self) -> Result<Option<[u8; LEN]>, Self::Error> {
40        match self {
41            Self::Null => Ok(None),
42            SqliteType::Blob(value) => <[u8; LEN]>::try_from(value).map(Some)
43                .map_err(|_| err!("Failed to convert from SQLite type")),
44            _ => Err(err!("Failed to convert from SQLite type")),
45        }
46    }
47}
48impl<const LEN: usize> TryFrom<[u8; LEN]> for SqliteType {
49    type Error = Error;
50
51    fn try_from(value: [u8; LEN]) -> Result<Self, Self::Error> {
52        Ok(SqliteType::Blob(value.into()))
53    }
54}
55impl<const LEN: usize> TryFrom<Option<[u8; LEN]>> for SqliteType {
56    type Error = Error;
57
58    fn try_from(value: Option<[u8; LEN]>) -> Result<Self, Self::Error> {
59        match value {
60            None => Ok(Self::Null),
61            Some(value) => Ok(SqliteType::Blob(value.into())),
62        }
63    }
64}
65
66// Generic conversions
67macro_rules! impl_sqlitetype_conversion {
68    (from: $variant:path => $type:ty) => {
69        impl TryInto<$type> for SqliteType {
70            type Error = Error;
71
72            fn try_into(self) -> Result<$type, Self::Error> {
73                match self {
74                    $variant(value) => <$type>::try_from(value)
75                        .map_err(|e| err!(with: e, "Failed to convert from SQLite type")),
76                    _ => Err(err!("Failed to convert from SQLite type"))
77                }
78            }
79        }
80        impl TryInto<Option<$type>> for SqliteType {
81            type Error = Error;
82
83            fn try_into(self) -> Result<Option<$type>, Self::Error> {
84                match self {
85                    Self::Null => Ok(None),
86                    $variant(value) => <$type>::try_from(value).map(Some)
87                        .map_err(|e| err!(with: e, "Failed to convert from SQLite type")),
88                    _ => Err(err!("Failed to convert from SQLite type"))
89                }
90            }
91        }
92    };
93    (into: $type:ty => $intermediate:ty => $variant:path) => {
94        impl TryFrom<$type> for SqliteType {
95            type Error = Error;
96
97            fn try_from(value: $type) -> Result<Self, Self::Error> {
98                <$intermediate>::try_from(value).map($variant)
99                    .map_err(|e| err!(with: e, "Failed to convert into SQLite type"))
100            }
101        }
102        impl TryFrom<Option<$type>> for SqliteType {
103            type Error = Error;
104
105            fn try_from(value: Option<$type>) -> Result<Self, Self::Error> {
106                match value {
107                    None => Ok(Self::Null),
108                    Some(value) => <$intermediate>::try_from(value).map($variant)
109                        .map_err(|e| err!(with: e, "Failed to convert into SQLite type")),
110                }
111            }
112        }
113    };
114    ($type:ty => $intermediate:ty => $variant:path) => {
115        impl_sqlitetype_conversion!(from: $variant => $type);
116        impl_sqlitetype_conversion!(into: $type => $intermediate => $variant);
117    };
118}
119// Integers
120impl_sqlitetype_conversion!(usize => i64 => SqliteType::Integer);
121impl_sqlitetype_conversion!(isize => i64 => SqliteType::Integer);
122impl_sqlitetype_conversion!(u128 => i64 => SqliteType::Integer);
123impl_sqlitetype_conversion!(i128 => i64 => SqliteType::Integer);
124impl_sqlitetype_conversion!(u64 => i64 => SqliteType::Integer);
125impl_sqlitetype_conversion!(i64 => i64 => SqliteType::Integer);
126impl_sqlitetype_conversion!(u32 => i64 => SqliteType::Integer);
127impl_sqlitetype_conversion!(i32 => i64 => SqliteType::Integer);
128impl_sqlitetype_conversion!(u16 => i64 => SqliteType::Integer);
129impl_sqlitetype_conversion!(i16 => i64 => SqliteType::Integer);
130impl_sqlitetype_conversion!(u8 => i64 => SqliteType::Integer);
131impl_sqlitetype_conversion!(i8 => i64 => SqliteType::Integer);
132// Floats
133impl_sqlitetype_conversion!(f64 => f64 => SqliteType::Real);
134impl_sqlitetype_conversion!(into: f32 => f64 => SqliteType::Real);
135// Strings
136impl_sqlitetype_conversion!(String => String => SqliteType::Text);
137impl_sqlitetype_conversion!(into: &str => String => SqliteType::Text);
138impl_sqlitetype_conversion!(from: SqliteType::Text => Arc<String>);
139// Bytes
140impl_sqlitetype_conversion!(Vec<u8> => Vec<u8> => SqliteType::Blob);
141impl_sqlitetype_conversion!(into: &[u8] => Vec<u8> => SqliteType::Blob);
142impl_sqlitetype_conversion!(from: SqliteType::Blob => Arc<Vec<u8>>);