Skip to main content

reifydb_core/value/column/buffer/
get.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use num_traits::NumCast;
5use reifydb_type::{
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
51macro_rules! impl_from_column_data_numeric {
52	($($t:ty),*) => { $(
53		impl FromColumnBuffer for $t {
54			fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
55				match data {
56					ColumnBuffer::Int1(c) => c.get(index).and_then(|v| NumCast::from(*v)),
57					ColumnBuffer::Int2(c) => c.get(index).and_then(|v| NumCast::from(*v)),
58					ColumnBuffer::Int4(c) => c.get(index).and_then(|v| NumCast::from(*v)),
59					ColumnBuffer::Int8(c) => c.get(index).and_then(|v| NumCast::from(*v)),
60					ColumnBuffer::Int16(c) => c.get(index).and_then(|v| NumCast::from(*v)),
61					ColumnBuffer::Uint1(c) => c.get(index).and_then(|v| NumCast::from(*v)),
62					ColumnBuffer::Uint2(c) => c.get(index).and_then(|v| NumCast::from(*v)),
63					ColumnBuffer::Uint4(c) => c.get(index).and_then(|v| NumCast::from(*v)),
64					ColumnBuffer::Uint8(c) => c.get(index).and_then(|v| NumCast::from(*v)),
65					ColumnBuffer::Uint16(c) => c.get(index).and_then(|v| NumCast::from(*v)),
66					ColumnBuffer::Float4(c) => c.get(index).and_then(|v| NumCast::from(*v)),
67					ColumnBuffer::Float8(c) => c.get(index).and_then(|v| NumCast::from(*v)),
68					ColumnBuffer::Int { container, .. } => container.get(index).and_then(|v| NumCast::from(v.0.clone())),
69					ColumnBuffer::Uint { container, .. } => container.get(index).and_then(|v| NumCast::from(v.0.clone())),
70					_ => None,
71				}
72			}
73		}
74	)* };
75}
76
77impl_from_column_data_numeric!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);
78
79impl FromColumnBuffer for bool {
80	fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
81		match data {
82			ColumnBuffer::Bool(c) => c.get(index),
83			_ => None,
84		}
85	}
86}
87
88impl FromColumnBuffer for String {
89	fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
90		match data {
91			ColumnBuffer::Utf8 {
92				container,
93				..
94			} => container.get(index).map(str::to_string),
95			_ => None,
96		}
97	}
98}
99
100impl FromColumnBuffer for Date {
101	fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
102		match data {
103			ColumnBuffer::Date(c) => c.get(index).copied(),
104			_ => None,
105		}
106	}
107}
108
109impl FromColumnBuffer for DateTime {
110	fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
111		match data {
112			ColumnBuffer::DateTime(c) => c.get(index).copied(),
113			_ => None,
114		}
115	}
116}
117
118impl FromColumnBuffer for Time {
119	fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
120		match data {
121			ColumnBuffer::Time(c) => c.get(index).copied(),
122			_ => None,
123		}
124	}
125}
126
127impl FromColumnBuffer for Duration {
128	fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
129		match data {
130			ColumnBuffer::Duration(c) => c.get(index).copied(),
131			_ => None,
132		}
133	}
134}
135
136impl FromColumnBuffer for Uuid4 {
137	fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
138		match data {
139			ColumnBuffer::Uuid4(c) => c.get(index).copied(),
140			_ => None,
141		}
142	}
143}
144
145impl FromColumnBuffer for Uuid7 {
146	fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
147		match data {
148			ColumnBuffer::Uuid7(c) => c.get(index).copied(),
149			_ => None,
150		}
151	}
152}
153
154impl FromColumnBuffer for Int {
155	fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
156		match data {
157			ColumnBuffer::Int {
158				container,
159				..
160			} => container.get(index).cloned(),
161			_ => None,
162		}
163	}
164}
165
166impl FromColumnBuffer for Uint {
167	fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
168		match data {
169			ColumnBuffer::Uint {
170				container,
171				..
172			} => container.get(index).cloned(),
173			_ => None,
174		}
175	}
176}
177
178impl FromColumnBuffer for Decimal {
179	fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
180		match data {
181			ColumnBuffer::Decimal {
182				container,
183				..
184			} => container.get(index).cloned(),
185			_ => None,
186		}
187	}
188}
189
190impl FromColumnBuffer for IdentityId {
191	fn from_column_buffer(data: &ColumnBuffer, index: usize) -> Option<Self> {
192		match data {
193			ColumnBuffer::IdentityId(c) => c.get(index),
194			_ => None,
195		}
196	}
197}