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