drizzle_postgres/values/
insert.rs1use super::{OwnedPostgresValue, PostgresValue};
4use crate::prelude::*;
5use core::marker::PhantomData;
6use drizzle_core::{
7 ToSQL, TypedPlaceholder, param::Param, placeholder::Placeholder, sql::SQL, sql::SQLChunk,
8 traits::SQLParam,
9};
10
11#[cfg(feature = "uuid")]
12use uuid::Uuid;
13
14#[doc(hidden)]
19#[derive(Debug, Clone)]
20pub struct ValueWrapper<'a, V: SQLParam, T> {
21 pub value: SQL<'a, V>,
22 pub _phantom: PhantomData<T>,
23}
24
25impl<'a, V: SQLParam, T> ValueWrapper<'a, V, T> {
26 pub const fn new<U>(value: SQL<'a, V>) -> ValueWrapper<'a, V, U> {
27 ValueWrapper {
28 value,
29 _phantom: PhantomData,
30 }
31 }
32}
33
34#[derive(Debug, Clone, Default)]
40#[allow(clippy::large_enum_variant)]
41pub enum PostgresInsertValue<'a, V: SQLParam, T> {
42 #[default]
44 Omit,
45 Null,
47 Value(ValueWrapper<'a, V, T>),
49}
50
51impl<'a, T> PostgresInsertValue<'a, PostgresValue<'a>, T> {
52 #[must_use]
58 pub fn into_owned(self) -> PostgresInsertValue<'static, PostgresValue<'static>, T> {
59 match self {
60 PostgresInsertValue::Omit => PostgresInsertValue::Omit,
61 PostgresInsertValue::Null => PostgresInsertValue::Null,
62 PostgresInsertValue::Value(wrapper) => {
63 let static_sql = wrapper
64 .value
65 .into_owned_with(|value| PostgresValue::from(OwnedPostgresValue::from(value)));
66 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'static>, T>::new(
67 static_sql,
68 ))
69 }
70 }
71 }
72}
73
74impl<'a, T> From<T> for PostgresInsertValue<'a, PostgresValue<'a>, T>
84where
85 T: TryInto<PostgresValue<'a>>,
86{
87 fn from(value: T) -> Self {
88 let sql = SQL::from(
91 TryInto::<PostgresValue<'a>>::try_into(value).unwrap_or_else(|_| {
92 panic!(
93 "could not convert a `{}` to a PostgreSQL value",
94 core::any::type_name::<T>()
95 )
96 }),
97 );
98 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, T>::new(sql))
99 }
100}
101
102impl<'a> From<&str> for PostgresInsertValue<'a, PostgresValue<'a>, String> {
104 fn from(value: &str) -> Self {
105 let postgres_value = SQL::param(Cow::Owned(PostgresValue::from(value.to_string())));
106 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, String>::new(
107 postgres_value,
108 ))
109 }
110}
111
112impl<'a, T> From<Placeholder> for PostgresInsertValue<'a, PostgresValue<'a>, T> {
114 fn from(placeholder: Placeholder) -> Self {
115 let chunk = SQLChunk::Param(Param {
116 placeholder,
117 value: None,
118 });
119 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, T>::new(
120 core::iter::once(chunk).collect(),
121 ))
122 }
123}
124
125impl<'a, M: drizzle_core::types::DataType, N: drizzle_core::expr::Nullability, T>
126 From<TypedPlaceholder<M, N>> for PostgresInsertValue<'a, PostgresValue<'a>, T>
127{
128 fn from(typed: TypedPlaceholder<M, N>) -> Self {
129 Placeholder::from(typed).into()
130 }
131}
132
133impl<'a, T> From<Option<T>> for PostgresInsertValue<'a, PostgresValue<'a>, T>
135where
136 T: ToSQL<'a, PostgresValue<'a>>,
137{
138 fn from(value: Option<T>) -> Self {
139 value.map_or(PostgresInsertValue::Omit, |v| {
140 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, T>::new(v.to_sql()))
141 })
142 }
143}
144
145#[cfg(feature = "uuid")]
147impl<'a> From<Uuid> for PostgresInsertValue<'a, PostgresValue<'a>, String> {
148 fn from(value: Uuid) -> Self {
149 let postgres_value = PostgresValue::Uuid(value);
150 let sql = SQL::param(postgres_value);
151 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, String>::new(sql))
152 }
153}
154
155#[cfg(feature = "uuid")]
156impl<'a> From<&'a Uuid> for PostgresInsertValue<'a, PostgresValue<'a>, String> {
157 fn from(value: &'a Uuid) -> Self {
158 let postgres_value = PostgresValue::Uuid(*value);
159 let sql = SQL::param(postgres_value);
160 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, String>::new(sql))
161 }
162}