arrow_buffer/builder/
offset.rs1use std::ops::Deref;
19
20use crate::{ArrowNativeType, OffsetBuffer};
21
22#[derive(Debug)]
24pub struct OffsetBufferBuilder<O: ArrowNativeType> {
25 offsets: Vec<O>,
26 last_offset: usize,
27}
28
29impl<O: ArrowNativeType> OffsetBufferBuilder<O> {
30 pub fn new(capacity: usize) -> Self {
32 let mut offsets = Vec::with_capacity(capacity + 1);
33 offsets.push(O::usize_as(0));
34 Self {
35 offsets,
36 last_offset: 0,
37 }
38 }
39
40 #[inline]
46 pub fn push_length(&mut self, length: usize) {
47 self.last_offset = self.last_offset.checked_add(length).expect("overflow");
48 self.offsets.push(O::usize_as(self.last_offset))
49 }
50
51 #[inline]
53 pub fn reserve(&mut self, additional: usize) {
54 self.offsets.reserve(additional);
55 }
56
57 pub fn finish(self) -> OffsetBuffer<O> {
63 O::from_usize(self.last_offset).expect("overflow");
64 unsafe { OffsetBuffer::new_unchecked(self.offsets.into()) }
65 }
66
67 pub fn finish_cloned(&self) -> OffsetBuffer<O> {
73 let cloned = Self {
74 offsets: self.offsets.clone(),
75 last_offset: self.last_offset,
76 };
77 cloned.finish()
78 }
79}
80
81impl<O: ArrowNativeType> Deref for OffsetBufferBuilder<O> {
82 type Target = [O];
83
84 fn deref(&self) -> &Self::Target {
85 self.offsets.as_ref()
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use crate::OffsetBufferBuilder;
92
93 #[test]
94 fn test_basic() {
95 let mut builder = OffsetBufferBuilder::<i32>::new(5);
96 assert_eq!(builder.len(), 1);
97 assert_eq!(&*builder, &[0]);
98 let finished = builder.finish_cloned();
99 assert_eq!(finished.len(), 1);
100 assert_eq!(&*finished, &[0]);
101
102 builder.push_length(2);
103 builder.push_length(6);
104 builder.push_length(0);
105 builder.push_length(13);
106
107 let finished = builder.finish();
108 assert_eq!(&*finished, &[0, 2, 8, 8, 21]);
109 }
110
111 #[test]
112 #[should_panic(expected = "overflow")]
113 fn test_usize_overflow() {
114 let mut builder = OffsetBufferBuilder::<i32>::new(5);
115 builder.push_length(1);
116 builder.push_length(usize::MAX);
117 builder.finish();
118 }
119
120 #[test]
121 #[should_panic(expected = "overflow")]
122 fn test_i32_overflow() {
123 let mut builder = OffsetBufferBuilder::<i32>::new(5);
124 builder.push_length(1);
125 builder.push_length(i32::MAX as usize);
126 builder.finish();
127 }
128}