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)]
36#[allow(clippy::large_enum_variant)]
37pub enum PostgresInsertValue<'a, V: SQLParam, T> {
38 #[default]
40 Omit,
41 Null,
43 Value(ValueWrapper<'a, V, T>),
45}
46
47impl<'a, T> PostgresInsertValue<'a, PostgresValue<'a>, T> {
48 #[must_use]
54 pub fn into_owned(self) -> PostgresInsertValue<'static, PostgresValue<'static>, T> {
55 match self {
56 PostgresInsertValue::Omit => PostgresInsertValue::Omit,
57 PostgresInsertValue::Null => PostgresInsertValue::Null,
58 PostgresInsertValue::Value(wrapper) => {
59 let static_sql = wrapper
60 .value
61 .into_owned_with(|value| PostgresValue::from(OwnedPostgresValue::from(value)));
62 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'static>, T>::new(
63 static_sql,
64 ))
65 }
66 }
67 }
68}
69
70impl<'a, T> From<T> for PostgresInsertValue<'a, PostgresValue<'a>, T>
80where
81 T: TryInto<PostgresValue<'a>>,
82{
83 fn from(value: T) -> Self {
84 let sql = SQL::from(
87 TryInto::<PostgresValue<'a>>::try_into(value).unwrap_or_else(|_| {
88 panic!(
89 "could not convert a `{}` to a PostgreSQL value",
90 core::any::type_name::<T>()
91 )
92 }),
93 );
94 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, T>::new(sql))
95 }
96}
97
98impl<'a> From<&str> for PostgresInsertValue<'a, PostgresValue<'a>, String> {
100 fn from(value: &str) -> Self {
101 let postgres_value = SQL::param(Cow::Owned(PostgresValue::from(value.to_string())));
102 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, String>::new(
103 postgres_value,
104 ))
105 }
106}
107
108impl<'a, T> From<Placeholder> for PostgresInsertValue<'a, PostgresValue<'a>, T> {
110 fn from(placeholder: Placeholder) -> Self {
111 let chunk = SQLChunk::Param(Param {
112 placeholder,
113 value: None,
114 });
115 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, T>::new(
116 core::iter::once(chunk).collect(),
117 ))
118 }
119}
120
121impl<'a, M: drizzle_core::types::DataType, N: drizzle_core::expr::Nullability, T>
122 From<TypedPlaceholder<M, N>> for PostgresInsertValue<'a, PostgresValue<'a>, T>
123{
124 fn from(typed: TypedPlaceholder<M, N>) -> Self {
125 Placeholder::from(typed).into()
126 }
127}
128
129impl<'a, T> From<Option<T>> for PostgresInsertValue<'a, PostgresValue<'a>, T>
131where
132 T: ToSQL<'a, PostgresValue<'a>>,
133{
134 fn from(value: Option<T>) -> Self {
135 value.map_or(PostgresInsertValue::Omit, |v| {
136 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, T>::new(v.to_sql()))
137 })
138 }
139}
140
141#[cfg(feature = "uuid")]
143impl<'a> From<Uuid> for PostgresInsertValue<'a, PostgresValue<'a>, String> {
144 fn from(value: Uuid) -> Self {
145 let postgres_value = PostgresValue::Uuid(value);
146 let sql = SQL::param(postgres_value);
147 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, String>::new(sql))
148 }
149}
150
151#[cfg(feature = "uuid")]
152impl<'a> From<&'a Uuid> for PostgresInsertValue<'a, PostgresValue<'a>, String> {
153 fn from(value: &'a Uuid) -> Self {
154 let postgres_value = PostgresValue::Uuid(*value);
155 let sql = SQL::param(postgres_value);
156 PostgresInsertValue::Value(ValueWrapper::<PostgresValue<'a>, String>::new(sql))
157 }
158}