1use crate::{err, error::Error};
4use core::ffi::c_int;
5
6#[derive(Debug, Clone, PartialEq)]
8pub enum SqliteType {
9 Null,
11 Integer(i64),
13 Real(f64),
15 Text(String),
17 Blob(Vec<u8>),
19}
20macro_rules! impl_sqlitetype_conversion {
21 (from: $variant:path => $type:ty) => {
22 impl TryInto<$type> for SqliteType {
23 type Error = Error;
24
25 fn try_into(self) -> Result<$type, Self::Error> {
26 match self {
27 $variant(value) => <$type>::try_from(value)
28 .map_err(|e| err!(with: e, "Failed to from SQLite type")),
29 _ => Err(err!("Failed to convert from SQLite type"))
30 }
31 }
32 }
33 impl TryInto<Option<$type>> for SqliteType {
34 type Error = Error;
35
36 fn try_into(self) -> Result<Option<$type>, Self::Error> {
37 match self {
38 Self::Null => Ok(None),
39 $variant(value) => <$type>::try_from(value)
40 .map(Some).map_err(|e| err!(with: e, "Failed to from SQLite type")),
41 _ => Err(err!("Failed to convert from SQLite type"))
42 }
43 }
44 }
45 };
46 (into: $type:ty => $intermediate:ty => $variant:path) => {
47 impl TryFrom<$type> for SqliteType {
48 type Error = Error;
49
50 fn try_from(value: $type) -> Result<Self, Self::Error> {
51 <$intermediate>::try_from(value)
52 .map($variant).map_err(|e| err!(with: e, "Failed to convert into SQLite type"))
53 }
54 }
55 impl TryFrom<Option<$type>> for SqliteType {
56 type Error = Error;
57
58 fn try_from(value: Option<$type>) -> Result<Self, Self::Error> {
59 match value {
60 None => Ok(Self::Null),
61 Some(value) => <$intermediate>::try_from(value)
62 .map($variant).map_err(|e| err!(with: e, "Failed to convert into SQLite type")),
63 }
64 }
65 }
66 };
67 ($type:ty => $intermediate:ty => $variant:path) => {
68 impl_sqlitetype_conversion!(from: $variant => $type);
69 impl_sqlitetype_conversion!(into: $type => $intermediate => $variant);
70 };
71}
72impl_sqlitetype_conversion!(usize => i64 => SqliteType::Integer);
73impl_sqlitetype_conversion!(isize => i64 => SqliteType::Integer);
74impl_sqlitetype_conversion!(u128 => i64 => SqliteType::Integer);
75impl_sqlitetype_conversion!(i128 => i64 => SqliteType::Integer);
76impl_sqlitetype_conversion!(u64 => i64 => SqliteType::Integer);
77impl_sqlitetype_conversion!(i64 => i64 => SqliteType::Integer);
78impl_sqlitetype_conversion!(u32 => i64 => SqliteType::Integer);
79impl_sqlitetype_conversion!(i32 => i64 => SqliteType::Integer);
80impl_sqlitetype_conversion!(u16 => i64 => SqliteType::Integer);
81impl_sqlitetype_conversion!(i16 => i64 => SqliteType::Integer);
82impl_sqlitetype_conversion!(u8 => i64 => SqliteType::Integer);
83impl_sqlitetype_conversion!(i8 => i64 => SqliteType::Integer);
84impl_sqlitetype_conversion!(f64 => f64 => SqliteType::Real);
85impl_sqlitetype_conversion!(into: f32 => f64 => SqliteType::Real);
86impl_sqlitetype_conversion!(String => String => SqliteType::Text);
87impl_sqlitetype_conversion!(into: &str => String => SqliteType::Text);
88impl_sqlitetype_conversion!(Vec<u8> => Vec<u8> => SqliteType::Blob);
89impl_sqlitetype_conversion!(into: &[u8] => Vec<u8> => SqliteType::Blob);
90
91#[derive(Debug)]
93pub struct PointerMut<T> {
94 ptr: *mut T,
96 on_drop: unsafe extern "C" fn(*mut T) -> c_int,
98}
99impl<T> PointerMut<T> {
100 pub fn new(ptr: *mut T, on_drop: unsafe extern "C" fn(*mut T) -> c_int) -> Self {
105 assert!(!ptr.is_null(), "cannot create an owned NULL pointer");
106 Self { ptr, on_drop }
107 }
108
109 pub const fn as_ptr(&self) -> *mut T {
111 self.ptr
112 }
113}
114impl<T> Drop for PointerMut<T> {
115 fn drop(&mut self) {
116 unsafe { (self.on_drop)(self.ptr) };
118 }
119}
120
121#[derive(Debug)]
123pub enum PointerMutFlex<'a, T> {
124 Borrowed(&'a mut PointerMut<T>),
126 Owned(PointerMut<T>),
128}
129impl<T> PointerMutFlex<'_, T> {
130 pub const fn as_ptr(&self) -> *mut T {
132 match self {
133 PointerMutFlex::Borrowed(pointer_ref) => pointer_ref.as_ptr(),
134 PointerMutFlex::Owned(pointer_mut) => pointer_mut.as_ptr(),
135 }
136 }
137}