Skip to main content

reifydb_core/value/column/data/
get.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
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::{ColumnData, data::with_container};
22
23pub trait FromColumnData: Sized {
24	fn from_column_data(data: &ColumnData, index: usize) -> Option<Self>;
25}
26
27impl ColumnData {
28	pub fn get_value(&self, index: usize) -> Value {
29		match self {
30			ColumnData::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: FromColumnData>(&self, index: usize) -> Option<T> {
47		T::from_column_data(self, index)
48	}
49}
50
51macro_rules! impl_from_column_data_numeric {
52	($($t:ty),*) => { $(
53		impl FromColumnData for $t {
54			fn from_column_data(data: &ColumnData, index: usize) -> Option<Self> {
55				match data {
56					ColumnData::Int1(c) => c.get(index).and_then(|v| NumCast::from(*v)),
57					ColumnData::Int2(c) => c.get(index).and_then(|v| NumCast::from(*v)),
58					ColumnData::Int4(c) => c.get(index).and_then(|v| NumCast::from(*v)),
59					ColumnData::Int8(c) => c.get(index).and_then(|v| NumCast::from(*v)),
60					ColumnData::Int16(c) => c.get(index).and_then(|v| NumCast::from(*v)),
61					ColumnData::Uint1(c) => c.get(index).and_then(|v| NumCast::from(*v)),
62					ColumnData::Uint2(c) => c.get(index).and_then(|v| NumCast::from(*v)),
63					ColumnData::Uint4(c) => c.get(index).and_then(|v| NumCast::from(*v)),
64					ColumnData::Uint8(c) => c.get(index).and_then(|v| NumCast::from(*v)),
65					ColumnData::Uint16(c) => c.get(index).and_then(|v| NumCast::from(*v)),
66					ColumnData::Float4(c) => c.get(index).and_then(|v| NumCast::from(*v)),
67					ColumnData::Float8(c) => c.get(index).and_then(|v| NumCast::from(*v)),
68					ColumnData::Int { container, .. } => container.get(index).and_then(|v| NumCast::from(v.0.clone())),
69					ColumnData::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 FromColumnData for bool {
80	fn from_column_data(data: &ColumnData, index: usize) -> Option<Self> {
81		match data {
82			ColumnData::Bool(c) => c.get(index),
83			_ => None,
84		}
85	}
86}
87
88impl FromColumnData for String {
89	fn from_column_data(data: &ColumnData, index: usize) -> Option<Self> {
90		match data {
91			ColumnData::Utf8 {
92				container,
93				..
94			} => container.get(index).cloned(),
95			_ => None,
96		}
97	}
98}
99
100impl FromColumnData for Date {
101	fn from_column_data(data: &ColumnData, index: usize) -> Option<Self> {
102		match data {
103			ColumnData::Date(c) => c.get(index).copied(),
104			_ => None,
105		}
106	}
107}
108
109impl FromColumnData for DateTime {
110	fn from_column_data(data: &ColumnData, index: usize) -> Option<Self> {
111		match data {
112			ColumnData::DateTime(c) => c.get(index).copied(),
113			_ => None,
114		}
115	}
116}
117
118impl FromColumnData for Time {
119	fn from_column_data(data: &ColumnData, index: usize) -> Option<Self> {
120		match data {
121			ColumnData::Time(c) => c.get(index).copied(),
122			_ => None,
123		}
124	}
125}
126
127impl FromColumnData for Duration {
128	fn from_column_data(data: &ColumnData, index: usize) -> Option<Self> {
129		match data {
130			ColumnData::Duration(c) => c.get(index).copied(),
131			_ => None,
132		}
133	}
134}
135
136impl FromColumnData for Uuid4 {
137	fn from_column_data(data: &ColumnData, index: usize) -> Option<Self> {
138		match data {
139			ColumnData::Uuid4(c) => c.get(index).copied(),
140			_ => None,
141		}
142	}
143}
144
145impl FromColumnData for Uuid7 {
146	fn from_column_data(data: &ColumnData, index: usize) -> Option<Self> {
147		match data {
148			ColumnData::Uuid7(c) => c.get(index).copied(),
149			_ => None,
150		}
151	}
152}
153
154impl FromColumnData for Int {
155	fn from_column_data(data: &ColumnData, index: usize) -> Option<Self> {
156		match data {
157			ColumnData::Int {
158				container,
159				..
160			} => container.get(index).cloned(),
161			_ => None,
162		}
163	}
164}
165
166impl FromColumnData for Uint {
167	fn from_column_data(data: &ColumnData, index: usize) -> Option<Self> {
168		match data {
169			ColumnData::Uint {
170				container,
171				..
172			} => container.get(index).cloned(),
173			_ => None,
174		}
175	}
176}
177
178impl FromColumnData for Decimal {
179	fn from_column_data(data: &ColumnData, index: usize) -> Option<Self> {
180		match data {
181			ColumnData::Decimal {
182				container,
183				..
184			} => container.get(index).cloned(),
185			_ => None,
186		}
187	}
188}
189
190impl FromColumnData for IdentityId {
191	fn from_column_data(data: &ColumnData, index: usize) -> Option<Self> {
192		match data {
193			ColumnData::IdentityId(c) => c.get(index),
194			_ => None,
195		}
196	}
197}