1use std::mem;
4
5use crate::database::Database;
6use crate::error::BoxDynError;
7
8#[must_use]
10pub enum IsNull {
11 Yes,
13
14 No,
18}
19
20impl IsNull {
21 pub fn is_null(&self) -> bool {
22 matches!(self, IsNull::Yes)
23 }
24}
25
26pub trait Encode<'q, DB: Database> {
28 fn encode(self, buf: &mut <DB as Database>::ArgumentBuffer<'q>) -> Result<IsNull, BoxDynError>
30 where
31 Self: Sized,
32 {
33 self.encode_by_ref(buf)
34 }
35
36 fn encode_by_ref(
41 &self,
42 buf: &mut <DB as Database>::ArgumentBuffer<'q>,
43 ) -> Result<IsNull, BoxDynError>;
44
45 fn produces(&self) -> Option<DB::TypeInfo> {
46 None
49 }
50
51 #[inline]
52 fn size_hint(&self) -> usize {
53 mem::size_of_val(self)
54 }
55}
56
57impl<'q, T, DB: Database> Encode<'q, DB> for &'_ T
58where
59 T: Encode<'q, DB>,
60{
61 #[inline]
62 fn encode(self, buf: &mut <DB as Database>::ArgumentBuffer<'q>) -> Result<IsNull, BoxDynError> {
63 <T as Encode<DB>>::encode_by_ref(self, buf)
64 }
65
66 #[inline]
67 fn encode_by_ref(
68 &self,
69 buf: &mut <DB as Database>::ArgumentBuffer<'q>,
70 ) -> Result<IsNull, BoxDynError> {
71 <&T as Encode<DB>>::encode(self, buf)
72 }
73
74 #[inline]
75 fn produces(&self) -> Option<DB::TypeInfo> {
76 (**self).produces()
77 }
78
79 #[inline]
80 fn size_hint(&self) -> usize {
81 (**self).size_hint()
82 }
83}
84
85#[macro_export]
86macro_rules! impl_encode_for_option {
87 ($DB:ident) => {
88 impl<'q, T> $crate::encode::Encode<'q, $DB> for Option<T>
89 where
90 T: $crate::encode::Encode<'q, $DB> + $crate::types::Type<$DB> + 'q,
91 {
92 #[inline]
93 fn produces(&self) -> Option<<$DB as $crate::database::Database>::TypeInfo> {
94 if let Some(v) = self {
95 v.produces()
96 } else {
97 T::type_info().into()
98 }
99 }
100
101 #[inline]
102 fn encode(
103 self,
104 buf: &mut <$DB as $crate::database::Database>::ArgumentBuffer<'q>,
105 ) -> Result<$crate::encode::IsNull, $crate::error::BoxDynError> {
106 if let Some(v) = self {
107 v.encode(buf)
108 } else {
109 Ok($crate::encode::IsNull::Yes)
110 }
111 }
112
113 #[inline]
114 fn encode_by_ref(
115 &self,
116 buf: &mut <$DB as $crate::database::Database>::ArgumentBuffer<'q>,
117 ) -> Result<$crate::encode::IsNull, $crate::error::BoxDynError> {
118 if let Some(v) = self {
119 v.encode_by_ref(buf)
120 } else {
121 Ok($crate::encode::IsNull::Yes)
122 }
123 }
124
125 #[inline]
126 fn size_hint(&self) -> usize {
127 self.as_ref().map_or(0, $crate::encode::Encode::size_hint)
128 }
129 }
130 };
131}