drizzle_sqlite/values/
insert.rs1use core::marker::PhantomData;
6
7use crate::prelude::*;
8use drizzle_core::{Placeholder, SQL, SQLParam, TypedPlaceholder};
9
10use super::{OwnedSQLiteValue, SQLiteValue};
11
12#[doc(hidden)]
13#[derive(Debug, Clone)]
14pub struct ValueWrapper<'a, V: SQLParam, T> {
15 pub value: SQL<'a, V>,
16 pub _phantom: PhantomData<T>,
17}
18
19impl<'a, V: SQLParam, T> ValueWrapper<'a, V, T> {
20 pub const fn new<U>(value: SQL<'a, V>) -> ValueWrapper<'a, V, U> {
21 ValueWrapper {
22 value,
23 _phantom: PhantomData,
24 }
25 }
26}
27
28#[derive(Debug, Clone, Default)]
30#[allow(clippy::large_enum_variant)]
31pub enum SQLiteInsertValue<'a, V: SQLParam, T> {
32 #[default]
34 Omit,
35 Null,
37 Value(ValueWrapper<'a, V, T>),
39}
40
41impl<'a, T> SQLiteInsertValue<'a, SQLiteValue<'a>, T> {
42 #[must_use]
48 pub fn into_owned(self) -> SQLiteInsertValue<'static, SQLiteValue<'static>, T> {
49 match self {
50 SQLiteInsertValue::Omit => SQLiteInsertValue::Omit,
51 SQLiteInsertValue::Null => SQLiteInsertValue::Null,
52 SQLiteInsertValue::Value(wrapper) => {
53 let static_sql = wrapper
54 .value
55 .into_owned_with(|value| SQLiteValue::from(OwnedSQLiteValue::from(value)));
56 SQLiteInsertValue::Value(ValueWrapper::<SQLiteValue<'static>, T>::new(static_sql))
57 }
58 }
59 }
60}
61
62impl<'a, T, U> From<T> for SQLiteInsertValue<'a, SQLiteValue<'a>, U>
70where
71 T: TryInto<SQLiteValue<'a>> + TryInto<U>,
72 U: TryInto<SQLiteValue<'a>>,
73{
74 fn from(value: T) -> Self {
75 let column_value = TryInto::<U>::try_into(value).unwrap_or_else(|_| {
78 panic!(
79 "a `{}` does not fit a `{}` column",
80 core::any::type_name::<T>(),
81 core::any::type_name::<U>()
82 )
83 });
84 let sql = SQL::from(
85 TryInto::<SQLiteValue<'a>>::try_into(column_value).unwrap_or_else(|_| {
86 panic!(
87 "could not convert a `{}` to a SQLite value",
88 core::any::type_name::<U>()
89 )
90 }),
91 );
92 SQLiteInsertValue::Value(ValueWrapper::<SQLiteValue<'a>, T>::new(sql))
93 }
94}
95
96impl<'a, T> From<Placeholder> for SQLiteInsertValue<'a, SQLiteValue<'a>, T> {
97 fn from(placeholder: Placeholder) -> Self {
98 use drizzle_core::{Param, SQLChunk};
99 let chunk = SQLChunk::Param(Param {
100 placeholder,
101 value: None,
102 });
103 SQLiteInsertValue::Value(ValueWrapper::<SQLiteValue<'a>, T>::new(
104 core::iter::once(chunk).collect(),
105 ))
106 }
107}
108
109impl<'a, M: drizzle_core::types::DataType, N: drizzle_core::expr::Nullability, T>
110 From<TypedPlaceholder<M, N>> for SQLiteInsertValue<'a, SQLiteValue<'a>, T>
111{
112 fn from(typed: TypedPlaceholder<M, N>) -> Self {
113 Placeholder::from(typed).into()
114 }
115}
116
117impl<'a, const N: usize> From<[u8; N]> for SQLiteInsertValue<'a, SQLiteValue<'a>, Vec<u8>> {
119 fn from(value: [u8; N]) -> Self {
120 let sqlite_value = SQLiteValue::Blob(Cow::Owned(value.to_vec()));
121 let sql = SQL::param(sqlite_value);
122 SQLiteInsertValue::Value(ValueWrapper::<SQLiteValue<'a>, Vec<u8>>::new(sql))
123 }
124}