reifydb_core/value/column/buffer/
get.rs1use num_traits::NumCast;
5use reifydb_value::{
6 storage::DataBitVec,
7 value::{
8 Value,
9 date::Date,
10 datetime::DateTime,
11 decimal::Decimal,
12 duration::Duration,
13 identity::IdentityId,
14 int::Int,
15 time::Time,
16 uint::Uint,
17 uuid::{Uuid4, Uuid7},
18 },
19};
20
21use crate::value::column::{ColumnBuffer, buffer::with_container};
22
23pub trait FromColumnBuffer: Sized {
24 fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self>;
25}
26
27impl ColumnBuffer {
28 pub fn get_value(&self, index: usize) -> Value {
29 match self {
30 ColumnBuffer::Option {
31 inner,
32 bitvec,
33 } => {
34 if index < DataBitVec::len(bitvec) && DataBitVec::get(bitvec, index) {
35 inner.get_value(index)
36 } else {
37 Value::None {
38 inner: inner.get_type(),
39 }
40 }
41 }
42 _ => with_container!(self, |c| c.get_value(index)),
43 }
44 }
45
46 pub fn get_as<T: FromColumnBuffer>(&self, index: usize) -> Option<T> {
47 T::from_column_buffer(self, index)
48 }
49
50 pub fn get_str(&self, index: usize) -> Option<&str> {
51 match self {
52 ColumnBuffer::Utf8 {
53 container,
54 ..
55 } => container.get(index),
56 ColumnBuffer::Option {
57 inner,
58 bitvec,
59 } => {
60 if index < DataBitVec::len(bitvec) && DataBitVec::get(bitvec, index) {
61 inner.get_str(index)
62 } else {
63 None
64 }
65 }
66 _ => None,
67 }
68 }
69
70 pub fn get_bytes(&self, index: usize) -> Option<&[u8]> {
71 match self {
72 ColumnBuffer::Blob {
73 container,
74 ..
75 } => container.get(index),
76 ColumnBuffer::Option {
77 inner,
78 bitvec,
79 } => {
80 if index < DataBitVec::len(bitvec) && DataBitVec::get(bitvec, index) {
81 inner.get_bytes(index)
82 } else {
83 None
84 }
85 }
86 _ => None,
87 }
88 }
89}
90
91macro_rules! impl_from_column_data_numeric {
92 ($($t:ty),*) => { $(
93 impl FromColumnBuffer for $t {
94 fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
95 match data {
96 ColumnBuffer::Int1(c) => c.get(index).and_then(|v| NumCast::from(*v)),
97 ColumnBuffer::Int2(c) => c.get(index).and_then(|v| NumCast::from(*v)),
98 ColumnBuffer::Int4(c) => c.get(index).and_then(|v| NumCast::from(*v)),
99 ColumnBuffer::Int8(c) => c.get(index).and_then(|v| NumCast::from(*v)),
100 ColumnBuffer::Int16(c) => c.get(index).and_then(|v| NumCast::from(*v)),
101 ColumnBuffer::Uint1(c) => c.get(index).and_then(|v| NumCast::from(*v)),
102 ColumnBuffer::Uint2(c) => c.get(index).and_then(|v| NumCast::from(*v)),
103 ColumnBuffer::Uint4(c) => c.get(index).and_then(|v| NumCast::from(*v)),
104 ColumnBuffer::Uint8(c) => c.get(index).and_then(|v| NumCast::from(*v)),
105 ColumnBuffer::Uint16(c) => c.get(index).and_then(|v| NumCast::from(*v)),
106 ColumnBuffer::Float4(c) => c.get(index).and_then(|v| NumCast::from(*v)),
107 ColumnBuffer::Float8(c) => c.get(index).and_then(|v| NumCast::from(*v)),
108 ColumnBuffer::Int { container, .. } => container.get(index).and_then(|v| NumCast::from(v.0.clone())),
109 ColumnBuffer::Uint { container, .. } => container.get(index).and_then(|v| NumCast::from(v.0.clone())),
110 _ => None,
111 }
112 }
113 }
114 )* };
115}
116
117impl_from_column_data_numeric!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);
118
119impl FromColumnBuffer for bool {
120 fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
121 match data {
122 ColumnBuffer::Bool(c) => c.get(index),
123 _ => None,
124 }
125 }
126}
127
128impl FromColumnBuffer for String {
129 fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
130 match data {
131 ColumnBuffer::Utf8 {
132 container,
133 ..
134 } => container.get(index).map(str::to_string),
135 _ => None,
136 }
137 }
138}
139
140impl FromColumnBuffer for Vec<u8> {
141 fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
142 match data {
143 ColumnBuffer::Blob {
144 container,
145 ..
146 } => container.get(index).map(<[u8]>::to_vec),
147 _ => None,
148 }
149 }
150}
151
152impl FromColumnBuffer for Date {
153 fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
154 match data {
155 ColumnBuffer::Date(c) => c.get(index).copied(),
156 _ => None,
157 }
158 }
159}
160
161impl FromColumnBuffer for DateTime {
162 fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
163 match data {
164 ColumnBuffer::DateTime(c) => c.get(index).copied(),
165 _ => None,
166 }
167 }
168}
169
170impl FromColumnBuffer for Time {
171 fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
172 match data {
173 ColumnBuffer::Time(c) => c.get(index).copied(),
174 _ => None,
175 }
176 }
177}
178
179impl FromColumnBuffer for Duration {
180 fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
181 match data {
182 ColumnBuffer::Duration(c) => c.get(index).copied(),
183 _ => None,
184 }
185 }
186}
187
188impl FromColumnBuffer for Uuid4 {
189 fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
190 match data {
191 ColumnBuffer::Uuid4(c) => c.get(index).copied(),
192 _ => None,
193 }
194 }
195}
196
197impl FromColumnBuffer for Uuid7 {
198 fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
199 match data {
200 ColumnBuffer::Uuid7(c) => c.get(index).copied(),
201 _ => None,
202 }
203 }
204}
205
206impl FromColumnBuffer for Int {
207 fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
208 match data {
209 ColumnBuffer::Int {
210 container,
211 ..
212 } => container.get(index).cloned(),
213 _ => None,
214 }
215 }
216}
217
218impl FromColumnBuffer for Uint {
219 fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
220 match data {
221 ColumnBuffer::Uint {
222 container,
223 ..
224 } => container.get(index).cloned(),
225 _ => None,
226 }
227 }
228}
229
230impl FromColumnBuffer for Decimal {
231 fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
232 match data {
233 ColumnBuffer::Decimal {
234 container,
235 ..
236 } => container.get(index).cloned(),
237 _ => None,
238 }
239 }
240}
241
242impl FromColumnBuffer for IdentityId {
243 fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
244 match data {
245 ColumnBuffer::IdentityId(c) => c.get(index),
246 _ => None,
247 }
248 }
249}