Skip to main content

odbc_api/buffers/
any_buffer.rs

1use std::{collections::HashSet, ffi::c_void};
2
3use odbc_sys::{CDataType, Date, Numeric, Time, Timestamp};
4
5use crate::{
6    Bit, Error,
7    buffers::columnar::{Resize, Slice},
8    columnar_bulk_inserter::BoundInputSlice,
9    error::TooLargeBufferSize,
10    handles::{CData, CDataMut, StatementRef},
11};
12
13use super::{
14    BinColumn, BinColumnSlice, BufferDesc, CharColumn, ColumnarBuffer, Indicator, Item,
15    NullableSlice, NullableSliceMut, TextColumn, TextColumnSlice, WCharColumn,
16    bin_column::BinColumnSliceMut,
17    column_with_indicator::{
18        OptBitColumn, OptDateColumn, OptF32Column, OptF64Column, OptI8Column, OptI16Column,
19        OptI32Column, OptI64Column, OptTimeColumn, OptTimestampColumn, OptU8Column,
20    },
21    columnar::ColumnBuffer,
22    text_column::TextColumnSliceMut,
23};
24
25#[deprecated(note = "Use BoxColumnBuffer instead")]
26/// Buffer holding a single column of either a result set or parameter
27#[derive(Debug)]
28pub enum AnyBuffer {
29    /// A buffer for holding both nullable and required binary data.
30    Binary(BinColumn),
31    /// A buffer for holding both nullable and required text data. Uses the system encoding for
32    /// character data.
33    Text(CharColumn),
34    /// A buffer for holding both nullable and required text data. Uses UTF-16 encoding
35    WText(WCharColumn),
36    Date(Vec<Date>),
37    Time(Vec<Time>),
38    Timestamp(Vec<Timestamp>),
39    F64(Vec<f64>),
40    F32(Vec<f32>),
41    I8(Vec<i8>),
42    I16(Vec<i16>),
43    I32(Vec<i32>),
44    I64(Vec<i64>),
45    U8(Vec<u8>),
46    Bit(Vec<Bit>),
47    Numeric(Vec<Numeric>),
48    NullableDate(OptDateColumn),
49    NullableTime(OptTimeColumn),
50    NullableTimestamp(OptTimestampColumn),
51    NullableF64(OptF64Column),
52    NullableF32(OptF32Column),
53    NullableI8(OptI8Column),
54    NullableI16(OptI16Column),
55    NullableI32(OptI32Column),
56    NullableI64(OptI64Column),
57    NullableU8(OptU8Column),
58    NullableBit(OptBitColumn),
59}
60
61#[expect(deprecated)]
62impl AnyBuffer {
63    /// Map buffer description to actual buffer.
64    pub fn try_from_desc(max_rows: usize, desc: BufferDesc) -> Result<Self, TooLargeBufferSize> {
65        let fallible_allocations = true;
66        Self::impl_from_desc(max_rows, desc, fallible_allocations)
67    }
68
69    /// Map buffer description to actual buffer.
70    pub fn from_desc(max_rows: usize, desc: BufferDesc) -> Self {
71        let fallible_allocations = false;
72        Self::impl_from_desc(max_rows, desc, fallible_allocations).unwrap()
73    }
74
75    /// Map buffer description to actual buffer.
76    fn impl_from_desc(
77        max_rows: usize,
78        desc: BufferDesc,
79        fallible_allocations: bool,
80    ) -> Result<Self, TooLargeBufferSize> {
81        let buffer = match desc {
82            BufferDesc::Binary { max_bytes } => {
83                if fallible_allocations {
84                    AnyBuffer::Binary(BinColumn::try_new(max_rows, max_bytes)?)
85                } else {
86                    AnyBuffer::Binary(BinColumn::new(max_rows, max_bytes))
87                }
88            }
89            BufferDesc::Text { max_str_len } => {
90                if fallible_allocations {
91                    AnyBuffer::Text(TextColumn::try_new(max_rows, max_str_len)?)
92                } else {
93                    AnyBuffer::Text(TextColumn::new(max_rows, max_str_len))
94                }
95            }
96            BufferDesc::WText { max_str_len } => {
97                if fallible_allocations {
98                    AnyBuffer::WText(TextColumn::try_new(max_rows, max_str_len)?)
99                } else {
100                    AnyBuffer::WText(TextColumn::new(max_rows, max_str_len))
101                }
102            }
103            BufferDesc::Date { nullable: false } => {
104                AnyBuffer::Date(vec![Date::default(); max_rows])
105            }
106            BufferDesc::Time { nullable: false } => {
107                AnyBuffer::Time(vec![Time::default(); max_rows])
108            }
109            BufferDesc::Timestamp { nullable: false } => {
110                AnyBuffer::Timestamp(vec![Timestamp::default(); max_rows])
111            }
112            BufferDesc::F64 { nullable: false } => AnyBuffer::F64(vec![f64::default(); max_rows]),
113            BufferDesc::F32 { nullable: false } => AnyBuffer::F32(vec![f32::default(); max_rows]),
114            BufferDesc::I8 { nullable: false } => AnyBuffer::I8(vec![i8::default(); max_rows]),
115            BufferDesc::I16 { nullable: false } => AnyBuffer::I16(vec![i16::default(); max_rows]),
116            BufferDesc::I32 { nullable: false } => AnyBuffer::I32(vec![i32::default(); max_rows]),
117            BufferDesc::I64 { nullable: false } => AnyBuffer::I64(vec![i64::default(); max_rows]),
118            BufferDesc::U8 { nullable: false } => AnyBuffer::U8(vec![u8::default(); max_rows]),
119            BufferDesc::Bit { nullable: false } => AnyBuffer::Bit(vec![Bit::default(); max_rows]),
120            BufferDesc::Numeric => AnyBuffer::Numeric(vec![Numeric::default(); max_rows]),
121            BufferDesc::Date { nullable: true } => {
122                AnyBuffer::NullableDate(OptDateColumn::new(max_rows))
123            }
124            BufferDesc::Time { nullable: true } => {
125                AnyBuffer::NullableTime(OptTimeColumn::new(max_rows))
126            }
127            BufferDesc::Timestamp { nullable: true } => {
128                AnyBuffer::NullableTimestamp(OptTimestampColumn::new(max_rows))
129            }
130            BufferDesc::F64 { nullable: true } => {
131                AnyBuffer::NullableF64(OptF64Column::new(max_rows))
132            }
133            BufferDesc::F32 { nullable: true } => {
134                AnyBuffer::NullableF32(OptF32Column::new(max_rows))
135            }
136            BufferDesc::I8 { nullable: true } => AnyBuffer::NullableI8(OptI8Column::new(max_rows)),
137            BufferDesc::I16 { nullable: true } => {
138                AnyBuffer::NullableI16(OptI16Column::new(max_rows))
139            }
140            BufferDesc::I32 { nullable: true } => {
141                AnyBuffer::NullableI32(OptI32Column::new(max_rows))
142            }
143            BufferDesc::I64 { nullable: true } => {
144                AnyBuffer::NullableI64(OptI64Column::new(max_rows))
145            }
146            BufferDesc::U8 { nullable: true } => AnyBuffer::NullableU8(OptU8Column::new(max_rows)),
147            BufferDesc::Bit { nullable: true } => {
148                AnyBuffer::NullableBit(OptBitColumn::new(max_rows))
149            }
150        };
151        Ok(buffer)
152    }
153
154    fn inner(&self) -> &dyn CData {
155        match self {
156            AnyBuffer::Binary(col) => col,
157            AnyBuffer::Text(col) => col,
158            AnyBuffer::WText(col) => col,
159            AnyBuffer::F64(col) => col,
160            AnyBuffer::F32(col) => col,
161            AnyBuffer::Date(col) => col,
162            AnyBuffer::Time(col) => col,
163            AnyBuffer::Timestamp(col) => col,
164            AnyBuffer::I8(col) => col,
165            AnyBuffer::I16(col) => col,
166            AnyBuffer::I32(col) => col,
167            AnyBuffer::I64(col) => col,
168            AnyBuffer::Bit(col) => col,
169            AnyBuffer::U8(col) => col,
170            AnyBuffer::Numeric(col) => col,
171            AnyBuffer::NullableF64(col) => col,
172            AnyBuffer::NullableF32(col) => col,
173            AnyBuffer::NullableDate(col) => col,
174            AnyBuffer::NullableTime(col) => col,
175            AnyBuffer::NullableTimestamp(col) => col,
176            AnyBuffer::NullableI8(col) => col,
177            AnyBuffer::NullableI16(col) => col,
178            AnyBuffer::NullableI32(col) => col,
179            AnyBuffer::NullableI64(col) => col,
180            AnyBuffer::NullableBit(col) => col,
181            AnyBuffer::NullableU8(col) => col,
182        }
183    }
184
185    fn inner_mut(&mut self) -> &mut dyn AnyBufferVariantMut {
186        match self {
187            AnyBuffer::Binary(col) => col,
188            AnyBuffer::Text(col) => col,
189            AnyBuffer::WText(col) => col,
190            AnyBuffer::F64(col) => col,
191            AnyBuffer::F32(col) => col,
192            AnyBuffer::Date(col) => col,
193            AnyBuffer::Time(col) => col,
194            AnyBuffer::Timestamp(col) => col,
195            AnyBuffer::I8(col) => col,
196            AnyBuffer::I16(col) => col,
197            AnyBuffer::I32(col) => col,
198            AnyBuffer::I64(col) => col,
199            AnyBuffer::Bit(col) => col,
200            AnyBuffer::U8(col) => col,
201            AnyBuffer::Numeric(col) => col,
202            AnyBuffer::NullableF64(col) => col,
203            AnyBuffer::NullableF32(col) => col,
204            AnyBuffer::NullableDate(col) => col,
205            AnyBuffer::NullableTime(col) => col,
206            AnyBuffer::NullableTimestamp(col) => col,
207            AnyBuffer::NullableI8(col) => col,
208            AnyBuffer::NullableI16(col) => col,
209            AnyBuffer::NullableI32(col) => col,
210            AnyBuffer::NullableI64(col) => col,
211            AnyBuffer::NullableBit(col) => col,
212            AnyBuffer::NullableU8(col) => col,
213        }
214    }
215}
216
217/// A trait implemented by all variants of [`AnyBuffer`]. This allows us to reduce the number of
218/// match statements for methods mutating [`AnyBuffer`], as we only need to implement
219/// [`AnyBuffer::inner_mut`].
220trait AnyBufferVariantMut: CDataMut + Resize {}
221
222impl<T> AnyBufferVariantMut for T where T: CDataMut + Resize {}
223
224#[expect(deprecated)]
225unsafe impl CData for AnyBuffer {
226    fn cdata_type(&self) -> CDataType {
227        self.inner().cdata_type()
228    }
229
230    fn indicator_ptr(&self) -> *const isize {
231        self.inner().indicator_ptr()
232    }
233
234    fn value_ptr(&self) -> *const c_void {
235        self.inner().value_ptr()
236    }
237
238    fn buffer_length(&self) -> isize {
239        self.inner().buffer_length()
240    }
241}
242
243#[expect(deprecated)]
244unsafe impl CDataMut for AnyBuffer {
245    fn mut_indicator_ptr(&mut self) -> *mut isize {
246        self.inner_mut().mut_indicator_ptr()
247    }
248
249    fn mut_value_ptr(&mut self) -> *mut c_void {
250        self.inner_mut().mut_value_ptr()
251    }
252}
253
254/// Flexible columnar buffer implementation. Bind this to a cursor to fetch values in bulk, or pass
255/// this as a parameter to a statement, to submit many parameters at once.
256#[deprecated(note = "ColumnarAnyBuffer is replaced by ColumnarDynBuffer")]
257#[expect(deprecated)]
258pub type ColumnarAnyBuffer = ColumnarBuffer<AnyBuffer>;
259
260#[expect(deprecated)]
261impl ColumnarAnyBuffer {
262    /// Allocates a [`ColumnarBuffer`] fitting the buffer descriptions.
263    pub fn from_descs(capacity: usize, descs: impl IntoIterator<Item = BufferDesc>) -> Self {
264        let mut column_index = 0;
265        let columns = descs
266            .into_iter()
267            .map(move |desc| {
268                let buffer = AnyBuffer::from_desc(capacity, desc);
269                column_index += 1;
270                (column_index, buffer)
271            })
272            .collect();
273        unsafe { ColumnarBuffer::new_unchecked(capacity, columns) }
274    }
275
276    /// Allocates a [`ColumnarBuffer`] fitting the buffer descriptions. If not enough memory is
277    /// available to allocate the buffers this function fails with
278    /// [`Error::TooLargeColumnBufferSize`]. This function is slower than [`Self::from_descs`]
279    /// which would just panic if not enough memory is available for allocation.
280    pub fn try_from_descs(
281        capacity: usize,
282        descs: impl IntoIterator<Item = BufferDesc>,
283    ) -> Result<Self, Error> {
284        let mut column_index = 0;
285        let columns = descs
286            .into_iter()
287            .map(move |desc| {
288                let buffer = AnyBuffer::try_from_desc(capacity, desc)
289                    .map_err(|source| source.add_context(column_index))?;
290                column_index += 1;
291                Ok::<_, Error>((column_index, buffer))
292            })
293            .collect::<Result<_, _>>()?;
294        Ok(unsafe { ColumnarBuffer::new_unchecked(capacity, columns) })
295    }
296
297    /// Allows you to pass the buffer descriptions together with a one based column index referring
298    /// the column, the buffer is supposed to bind to. This allows you also to ignore columns in a
299    /// result set, by not binding them at all. There is no restriction on the order of column
300    /// indices passed, but the function will panic, if the indices are not unique.
301    pub fn from_descs_and_indices(
302        max_rows: usize,
303        description: impl Iterator<Item = (u16, BufferDesc)>,
304    ) -> ColumnarBuffer<AnyBuffer> {
305        let columns: Vec<_> = description
306            .map(|(col_index, buffer_desc)| {
307                (col_index, AnyBuffer::from_desc(max_rows, buffer_desc))
308            })
309            .collect();
310
311        // Assert uniqueness of indices
312        let mut indices = HashSet::new();
313        if columns
314            .iter()
315            .any(move |&(col_index, _)| !indices.insert(col_index))
316        {
317            panic!("Column indices must be unique.")
318        }
319
320        ColumnarBuffer::new(columns)
321    }
322}
323
324/// A borrowed view on the valid rows in a column of a [`crate::buffers::ColumnarBuffer`].
325///
326/// For columns of fixed size types, which are guaranteed to not contain null, a direct access to
327/// the slice is offered. Buffers over nullable columns can be accessed via an iterator over
328/// options.
329#[derive(Debug, Clone, Copy)]
330pub enum AnySlice<'a> {
331    /// Nullable character data in the system encoding.
332    Text(TextColumnSlice<'a, u8>),
333    /// Nullable character data encoded in UTF-16.
334    WText(TextColumnSlice<'a, u16>),
335    Binary(BinColumnSlice<'a>),
336    Date(&'a [Date]),
337    Time(&'a [Time]),
338    Timestamp(&'a [Timestamp]),
339    F64(&'a [f64]),
340    F32(&'a [f32]),
341    I8(&'a [i8]),
342    I16(&'a [i16]),
343    I32(&'a [i32]),
344    I64(&'a [i64]),
345    U8(&'a [u8]),
346    Bit(&'a [Bit]),
347    Numeric(&'a [Numeric]),
348    NullableDate(NullableSlice<'a, Date>),
349    NullableTime(NullableSlice<'a, Time>),
350    NullableTimestamp(NullableSlice<'a, Timestamp>),
351    NullableF64(NullableSlice<'a, f64>),
352    NullableF32(NullableSlice<'a, f32>),
353    NullableI8(NullableSlice<'a, i8>),
354    NullableI16(NullableSlice<'a, i16>),
355    NullableI32(NullableSlice<'a, i32>),
356    NullableI64(NullableSlice<'a, i64>),
357    NullableU8(NullableSlice<'a, u8>),
358    NullableBit(NullableSlice<'a, Bit>),
359    NullableNumeric(NullableSlice<'a, Numeric>),
360}
361
362impl<'a> AnySlice<'a> {
363    /// This method is useful if you expect the variant to be [`AnySlice::Text`]. It allows you to
364    /// unwrap the inner column view without explictly matching it.
365    pub fn as_text_view(self) -> Option<TextColumnSlice<'a, u8>> {
366        if let Self::Text(view) = self {
367            Some(view)
368        } else {
369            None
370        }
371    }
372
373    /// This method is useful if you expect the variant to be [`AnySlice::WText`]. It allows you to
374    /// unwrap the inner column view without explictly matching it.
375    pub fn as_w_text_view(self) -> Option<TextColumnSlice<'a, u16>> {
376        if let Self::WText(view) = self {
377            Some(view)
378        } else {
379            None
380        }
381    }
382
383    /// This method is useful if you expect the variant to be [`AnySlice::Binary`]. It allows you to
384    /// unwrap the inner column view without explictly matching it.
385    pub fn as_bin_view(self) -> Option<BinColumnSlice<'a>> {
386        if let Self::Binary(view) = self {
387            Some(view)
388        } else {
389            None
390        }
391    }
392
393    /// Extract the array type from an [`AnySlice`].
394    pub fn as_slice<I: Item>(self) -> Option<&'a [I]> {
395        I::as_slice(self)
396    }
397
398    /// Extract the typed nullable buffer from an [`AnySlice`].
399    pub fn as_nullable_slice<I: Item>(self) -> Option<NullableSlice<'a, I>> {
400        I::as_nullable_slice(self)
401    }
402}
403
404#[expect(deprecated)]
405unsafe impl<'a> BoundInputSlice<'a> for AnyBuffer {
406    type SliceMut = AnySliceMut<'a>;
407
408    unsafe fn as_view_mut(
409        &'a mut self,
410        parameter_index: u16,
411        stmt: StatementRef<'a>,
412    ) -> Self::SliceMut {
413        let num_rows = self.capacity();
414        unsafe {
415            match self {
416                AnyBuffer::Binary(column) => {
417                    AnySliceMut::Binary(column.as_view_mut(parameter_index, stmt))
418                }
419                AnyBuffer::Text(column) => {
420                    AnySliceMut::Text(column.as_view_mut(parameter_index, stmt))
421                }
422                AnyBuffer::WText(column) => {
423                    AnySliceMut::WText(column.as_view_mut(parameter_index, stmt))
424                }
425                AnyBuffer::Date(column) => AnySliceMut::Date(column),
426                AnyBuffer::Time(column) => AnySliceMut::Time(column),
427                AnyBuffer::Timestamp(column) => AnySliceMut::Timestamp(column),
428                AnyBuffer::F64(column) => AnySliceMut::F64(column),
429                AnyBuffer::F32(column) => AnySliceMut::F32(column),
430                AnyBuffer::I8(column) => AnySliceMut::I8(column),
431                AnyBuffer::I16(column) => AnySliceMut::I16(column),
432                AnyBuffer::I32(column) => AnySliceMut::I32(column),
433                AnyBuffer::I64(column) => AnySliceMut::I64(column),
434                AnyBuffer::U8(column) => AnySliceMut::U8(column),
435                AnyBuffer::Bit(column) => AnySliceMut::Bit(column),
436                AnyBuffer::Numeric(column) => AnySliceMut::Numeric(column),
437                AnyBuffer::NullableDate(column) => {
438                    AnySliceMut::NullableDate(column.writer_n(num_rows))
439                }
440                AnyBuffer::NullableTime(column) => {
441                    AnySliceMut::NullableTime(column.writer_n(num_rows))
442                }
443                AnyBuffer::NullableTimestamp(column) => {
444                    AnySliceMut::NullableTimestamp(column.writer_n(num_rows))
445                }
446                AnyBuffer::NullableF64(column) => {
447                    AnySliceMut::NullableF64(column.writer_n(num_rows))
448                }
449                AnyBuffer::NullableF32(column) => {
450                    AnySliceMut::NullableF32(column.writer_n(num_rows))
451                }
452                AnyBuffer::NullableI8(column) => AnySliceMut::NullableI8(column.writer_n(num_rows)),
453                AnyBuffer::NullableI16(column) => {
454                    AnySliceMut::NullableI16(column.writer_n(num_rows))
455                }
456                AnyBuffer::NullableI32(column) => {
457                    AnySliceMut::NullableI32(column.writer_n(num_rows))
458                }
459                AnyBuffer::NullableI64(column) => {
460                    AnySliceMut::NullableI64(column.writer_n(num_rows))
461                }
462                AnyBuffer::NullableU8(column) => AnySliceMut::NullableU8(column.writer_n(num_rows)),
463                AnyBuffer::NullableBit(column) => {
464                    AnySliceMut::NullableBit(column.writer_n(num_rows))
465                }
466            }
467        }
468    }
469}
470
471/// A mutable slice of an input buffer, with runtime type information. Edit values in this slice in
472/// order to send parameters in bulk to a database.
473pub enum AnySliceMut<'a> {
474    Text(TextColumnSliceMut<'a, u8>),
475    /// Nullable character data encoded in UTF-16.
476    WText(TextColumnSliceMut<'a, u16>),
477    Binary(BinColumnSliceMut<'a>),
478    Date(&'a mut [Date]),
479    Time(&'a mut [Time]),
480    Timestamp(&'a mut [Timestamp]),
481    F64(&'a mut [f64]),
482    F32(&'a mut [f32]),
483    I8(&'a mut [i8]),
484    I16(&'a mut [i16]),
485    I32(&'a mut [i32]),
486    I64(&'a mut [i64]),
487    U8(&'a mut [u8]),
488    Bit(&'a mut [Bit]),
489    Numeric(&'a mut [Numeric]),
490    NullableDate(NullableSliceMut<'a, Date>),
491    NullableTime(NullableSliceMut<'a, Time>),
492    NullableTimestamp(NullableSliceMut<'a, Timestamp>),
493    NullableF64(NullableSliceMut<'a, f64>),
494    NullableF32(NullableSliceMut<'a, f32>),
495    NullableI8(NullableSliceMut<'a, i8>),
496    NullableI16(NullableSliceMut<'a, i16>),
497    NullableI32(NullableSliceMut<'a, i32>),
498    NullableI64(NullableSliceMut<'a, i64>),
499    NullableU8(NullableSliceMut<'a, u8>),
500    NullableBit(NullableSliceMut<'a, Bit>),
501}
502
503impl<'a> AnySliceMut<'a> {
504    /// This method is useful if you expect the variant to be [`AnySliceMut::Binary`]. It allows you
505    /// to unwrap the inner column view without explictly matching it.
506    pub fn as_bin_view(self) -> Option<BinColumnSliceMut<'a>> {
507        if let Self::Binary(view) = self {
508            Some(view)
509        } else {
510            None
511        }
512    }
513
514    /// This method is useful if you expect the variant to be [`AnySliceMut::Text`]. It allows you
515    /// to unwrap the inner column view without explictly matching it.
516    pub fn as_text_view(self) -> Option<TextColumnSliceMut<'a, u8>> {
517        if let Self::Text(view) = self {
518            Some(view)
519        } else {
520            None
521        }
522    }
523
524    /// This method is useful if you expect the variant to be [`AnySliceMut::WText`]. It allows you
525    /// to unwrap the inner column view without explictly matching it.
526    pub fn as_w_text_view(self) -> Option<TextColumnSliceMut<'a, u16>> {
527        if let Self::WText(view) = self {
528            Some(view)
529        } else {
530            None
531        }
532    }
533
534    /// Extract the array type from an [`AnySliceMut`].
535    pub fn as_slice<I: Item>(self) -> Option<&'a mut [I]> {
536        I::as_slice_mut(self)
537    }
538
539    /// Extract the typed nullable buffer from an [`AnySliceMut`].
540    pub fn as_nullable_slice<I: Item>(self) -> Option<NullableSliceMut<'a, I>> {
541        I::as_nullable_slice_mut(self)
542    }
543}
544
545#[expect(deprecated)]
546unsafe impl ColumnBuffer for AnyBuffer {
547    fn capacity(&self) -> usize {
548        match self {
549            AnyBuffer::Binary(col) => col.capacity(),
550            AnyBuffer::Text(col) => col.capacity(),
551            AnyBuffer::WText(col) => col.capacity(),
552            AnyBuffer::Date(col) => col.capacity(),
553            AnyBuffer::Time(col) => col.capacity(),
554            AnyBuffer::Timestamp(col) => col.capacity(),
555            AnyBuffer::F64(col) => col.capacity(),
556            AnyBuffer::F32(col) => col.capacity(),
557            AnyBuffer::I8(col) => col.capacity(),
558            AnyBuffer::I16(col) => col.capacity(),
559            AnyBuffer::I32(col) => col.capacity(),
560            AnyBuffer::I64(col) => col.capacity(),
561            AnyBuffer::U8(col) => col.capacity(),
562            AnyBuffer::Bit(col) => col.capacity(),
563            AnyBuffer::Numeric(col) => col.capacity(),
564            AnyBuffer::NullableDate(col) => col.capacity(),
565            AnyBuffer::NullableTime(col) => col.capacity(),
566            AnyBuffer::NullableTimestamp(col) => col.capacity(),
567            AnyBuffer::NullableF64(col) => col.capacity(),
568            AnyBuffer::NullableF32(col) => col.capacity(),
569            AnyBuffer::NullableI8(col) => col.capacity(),
570            AnyBuffer::NullableI16(col) => col.capacity(),
571            AnyBuffer::NullableI32(col) => col.capacity(),
572            AnyBuffer::NullableI64(col) => col.capacity(),
573            AnyBuffer::NullableU8(col) => col.capacity(),
574            AnyBuffer::NullableBit(col) => col.capacity(),
575        }
576    }
577
578    fn has_truncated_values(&self, num_rows: usize) -> Option<Indicator> {
579        match self {
580            AnyBuffer::Binary(col) => col.has_truncated_values(num_rows),
581            AnyBuffer::Text(col) => col.has_truncated_values(num_rows),
582            AnyBuffer::WText(col) => col.has_truncated_values(num_rows),
583            _ => None,
584        }
585    }
586}
587
588#[expect(deprecated)]
589unsafe impl Slice for AnyBuffer {
590    type Slice<'a> = AnySlice<'a>;
591
592    fn slice(&self, valid_rows: usize) -> AnySlice<'_> {
593        match self {
594            AnyBuffer::Binary(col) => AnySlice::Binary(col.view(valid_rows)),
595            AnyBuffer::Text(col) => AnySlice::Text(col.slice(valid_rows)),
596            AnyBuffer::WText(col) => AnySlice::WText(col.slice(valid_rows)),
597            AnyBuffer::Date(col) => AnySlice::Date(&col[0..valid_rows]),
598            AnyBuffer::Time(col) => AnySlice::Time(&col[0..valid_rows]),
599            AnyBuffer::Timestamp(col) => AnySlice::Timestamp(&col[0..valid_rows]),
600            AnyBuffer::F64(col) => AnySlice::F64(&col[0..valid_rows]),
601            AnyBuffer::F32(col) => AnySlice::F32(&col[0..valid_rows]),
602            AnyBuffer::I8(col) => AnySlice::I8(&col[0..valid_rows]),
603            AnyBuffer::I16(col) => AnySlice::I16(&col[0..valid_rows]),
604            AnyBuffer::I32(col) => AnySlice::I32(&col[0..valid_rows]),
605            AnyBuffer::I64(col) => AnySlice::I64(&col[0..valid_rows]),
606            AnyBuffer::U8(col) => AnySlice::U8(&col[0..valid_rows]),
607            AnyBuffer::Bit(col) => AnySlice::Bit(&col[0..valid_rows]),
608            AnyBuffer::Numeric(col) => AnySlice::Numeric(&col[0..valid_rows]),
609            AnyBuffer::NullableDate(col) => AnySlice::NullableDate(col.iter(valid_rows)),
610            AnyBuffer::NullableTime(col) => AnySlice::NullableTime(col.iter(valid_rows)),
611            AnyBuffer::NullableTimestamp(col) => AnySlice::NullableTimestamp(col.iter(valid_rows)),
612            AnyBuffer::NullableF64(col) => AnySlice::NullableF64(col.iter(valid_rows)),
613            AnyBuffer::NullableF32(col) => AnySlice::NullableF32(col.iter(valid_rows)),
614            AnyBuffer::NullableI8(col) => AnySlice::NullableI8(col.iter(valid_rows)),
615            AnyBuffer::NullableI16(col) => AnySlice::NullableI16(col.iter(valid_rows)),
616            AnyBuffer::NullableI32(col) => AnySlice::NullableI32(col.iter(valid_rows)),
617            AnyBuffer::NullableI64(col) => AnySlice::NullableI64(col.iter(valid_rows)),
618            AnyBuffer::NullableU8(col) => AnySlice::NullableU8(col.iter(valid_rows)),
619            AnyBuffer::NullableBit(col) => AnySlice::NullableBit(col.iter(valid_rows)),
620        }
621    }
622}
623
624#[expect(deprecated)]
625impl Resize for AnyBuffer {
626    fn resize(&mut self, new_capacity: usize) {
627        self.inner_mut().resize(new_capacity);
628    }
629}
630
631#[cfg(test)]
632mod tests {
633    use crate::buffers::{AnySlice, AnySliceMut, ColumnBuffer as _, Resize, columnar::Slice as _};
634
635    #[expect(deprecated)]
636    use super::AnyBuffer;
637
638    #[expect(deprecated)]
639    #[test]
640    fn any_buffer_is_resize() {
641        // Given an `AnyBuffer` with a capacity of 2 and values [1, 2]
642        let mut buffer = AnyBuffer::I32(vec![1, 2]);
643
644        // When we resize it to a capacity of 4
645        buffer.resize(4);
646
647        // Then the buffer should still have the same values in the first two positions and the
648        // remaining positions should be filled with default values (0 for i32)
649        assert_eq!(buffer.slice(4).as_slice(), Some([1i32, 2, 0, 0].as_slice()));
650        // And the capacity should be 4
651        assert_eq!(buffer.capacity(), 4);
652    }
653
654    #[expect(deprecated)]
655    #[test]
656    fn slice_should_only_contain_part_of_the_buffer() {
657        let buffer = AnyBuffer::I32(vec![1, 2, 3]);
658
659        let view = buffer.slice(2);
660
661        assert_eq!(Some([1, 2].as_slice()), view.as_slice::<i32>());
662    }
663
664    #[test]
665    fn slice_should_be_none_if_types_mismatch() {
666        let buffer = [1, 2, 3];
667        let view = AnySlice::I32(&buffer);
668        assert_eq!(None, view.as_slice::<i16>());
669    }
670
671    #[test]
672    fn slice_mut_should_be_none_if_types_mismatch() {
673        let mut buffer = [1, 2, 3];
674        let view = AnySliceMut::I32(&mut buffer);
675        assert_eq!(None, view.as_slice::<i16>());
676    }
677
678    #[test]
679    fn nullable_slice_should_be_none_if_buffer_is_non_nullable() {
680        let buffer = [1, 2, 3];
681        let view = AnySlice::I32(&buffer);
682        assert!(view.as_nullable_slice::<i32>().is_none());
683    }
684
685    #[test]
686    fn nullable_slice_mut_should_be_none_if_buffer_is_non_nullable() {
687        let mut buffer = [1, 2, 3];
688        let view = AnySliceMut::I32(&mut buffer);
689        assert!(view.as_nullable_slice::<i32>().is_none());
690    }
691}