1use odbc_sys::{Date, Time, Timestamp};
2
3use super::{AnySlice, AnySliceMut, BufferDesc, NullableSlice, NullableSliceMut};
4use crate::{BindParamDesc, Bit};
5
6pub trait Item: Sized + Copy {
37 fn bind_param_desc(nullable: bool) -> BindParamDesc;
39
40 #[deprecated(note = "Use `bind_param_desc` instead")]
54 fn buffer_desc(nullable: bool) -> BufferDesc;
55
56 fn as_slice(variant: AnySlice<'_>) -> Option<&[Self]>;
58 fn as_nullable_slice(variant: AnySlice<'_>) -> Option<NullableSlice<'_, Self>>;
60
61 fn as_slice_mut(variant: AnySliceMut<'_>) -> Option<&'_ mut [Self]>;
63
64 fn as_nullable_slice_mut(variant: AnySliceMut<'_>) -> Option<NullableSliceMut<'_, Self>>;
66}
67
68macro_rules! impl_item {
69 ($t:ident, $bind:ident, $plain:ident, $null:ident) => {
70 impl Item for $t {
71 fn bind_param_desc(nullable: bool) -> BindParamDesc {
72 BindParamDesc::$bind(nullable)
73 }
74
75 fn buffer_desc(nullable: bool) -> BufferDesc {
76 BufferDesc::$plain { nullable }
77 }
78
79 fn as_slice(variant: AnySlice<'_>) -> Option<&[Self]> {
80 match variant {
81 AnySlice::$plain(vals) => Some(vals),
82 _ => None,
83 }
84 }
85
86 fn as_nullable_slice(variant: AnySlice<'_>) -> Option<NullableSlice<'_, Self>> {
87 match variant {
88 AnySlice::$null(vals) => Some(vals),
89 _ => None,
90 }
91 }
92
93 fn as_slice_mut(variant: AnySliceMut<'_>) -> Option<&'_ mut [Self]> {
94 match variant {
95 AnySliceMut::$plain(vals) => Some(vals),
96 _ => None,
97 }
98 }
99
100 fn as_nullable_slice_mut(
101 variant: AnySliceMut<'_>,
102 ) -> Option<NullableSliceMut<'_, Self>> {
103 match variant {
104 AnySliceMut::$null(vals) => Some(vals),
105 _ => None,
106 }
107 }
108 }
109 };
110}
111
112impl_item!(f64, f64, F64, NullableF64);
113impl_item!(f32, f32, F32, NullableF32);
114impl_item!(u8, u8, U8, NullableU8);
115impl_item!(i8, i8, I8, NullableI8);
116impl_item!(i16, i16, I16, NullableI16);
117impl_item!(i32, i32, I32, NullableI32);
118impl_item!(i64, i64, I64, NullableI64);
119impl_item!(Date, date, Date, NullableDate);
120impl_item!(Time, time, Time, NullableTime);
121impl_item!(Bit, bit, Bit, NullableBit);
122
123const DEFAULT_TIME_PRECISION: i16 = 7;
128
129impl Item for Timestamp {
130 fn bind_param_desc(nullable: bool) -> BindParamDesc {
131 BindParamDesc::timestamp(nullable, DEFAULT_TIME_PRECISION)
132 }
133
134 fn buffer_desc(nullable: bool) -> BufferDesc {
135 BufferDesc::Timestamp { nullable }
136 }
137
138 fn as_slice(variant: AnySlice<'_>) -> Option<&[Self]> {
139 if let AnySlice::Timestamp(vals) = variant {
140 Some(vals)
141 } else {
142 None
143 }
144 }
145
146 fn as_nullable_slice(variant: AnySlice<'_>) -> Option<NullableSlice<'_, Self>> {
147 if let AnySlice::NullableTimestamp(vals) = variant {
148 Some(vals)
149 } else {
150 None
151 }
152 }
153
154 fn as_slice_mut(variant: AnySliceMut<'_>) -> Option<&'_ mut [Self]> {
155 if let AnySliceMut::Timestamp(vals) = variant {
156 Some(vals)
157 } else {
158 None
159 }
160 }
161
162 fn as_nullable_slice_mut(variant: AnySliceMut<'_>) -> Option<NullableSliceMut<'_, Self>> {
163 if let AnySliceMut::NullableTimestamp(vals) = variant {
164 Some(vals)
165 } else {
166 None
167 }
168 }
169}
170
171#[cfg(test)]
172mod tests {
173 use crate::{
174 BindParamDesc,
175 buffers::item::DEFAULT_TIME_PRECISION,
176 sys::{Date, Time, Timestamp},
177 };
178
179 use super::{Bit, Item as _};
180
181 #[test]
182 fn item_to_bind_param_desc() {
183 assert_eq!(BindParamDesc::i32(false), i32::bind_param_desc(false));
184 assert_eq!(BindParamDesc::i32(true), i32::bind_param_desc(true));
185 assert_eq!(BindParamDesc::f64(false), f64::bind_param_desc(false));
186 assert_eq!(BindParamDesc::f32(false), f32::bind_param_desc(false));
187 assert_eq!(BindParamDesc::u8(false), u8::bind_param_desc(false));
188 assert_eq!(BindParamDesc::i8(false), i8::bind_param_desc(false));
189 assert_eq!(BindParamDesc::i16(false), i16::bind_param_desc(false));
190 assert_eq!(BindParamDesc::i64(false), i64::bind_param_desc(false));
191 assert_eq!(BindParamDesc::date(false), Date::bind_param_desc(false));
192 assert_eq!(BindParamDesc::bit(false), Bit::bind_param_desc(false));
193 assert_eq!(BindParamDesc::time(false), Time::bind_param_desc(false));
194 assert_eq!(
195 BindParamDesc::timestamp(false, DEFAULT_TIME_PRECISION),
196 Timestamp::bind_param_desc(false)
197 );
198 }
199}