Skip to main content

reifydb_type/value/frame/
data.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use serde::{Deserialize, Serialize};
5
6use crate::{
7	storage::DataBitVec,
8	util::{
9		bitvec::BitVec,
10		float_format::{format_f32, format_f64},
11	},
12	value::{
13		Value,
14		container::{
15			any::AnyContainer, blob::BlobContainer, bool::BoolContainer, dictionary::DictionaryContainer,
16			identity_id::IdentityIdContainer, number::NumberContainer, temporal::TemporalContainer,
17			utf8::Utf8Container, uuid::UuidContainer,
18		},
19		date::Date,
20		datetime::DateTime,
21		decimal::Decimal,
22		duration::Duration,
23		int::Int,
24		time::Time,
25		r#type::Type,
26		uint::Uint,
27		uuid::{Uuid4, Uuid7},
28	},
29};
30
31#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
32pub enum FrameColumnData {
33	Bool(BoolContainer),
34	Float4(NumberContainer<f32>),
35	Float8(NumberContainer<f64>),
36	Int1(NumberContainer<i8>),
37	Int2(NumberContainer<i16>),
38	Int4(NumberContainer<i32>),
39	Int8(NumberContainer<i64>),
40	Int16(NumberContainer<i128>),
41	Uint1(NumberContainer<u8>),
42	Uint2(NumberContainer<u16>),
43	Uint4(NumberContainer<u32>),
44	Uint8(NumberContainer<u64>),
45	Uint16(NumberContainer<u128>),
46	Utf8(Utf8Container),
47	Date(TemporalContainer<Date>),
48	DateTime(TemporalContainer<DateTime>),
49	Time(TemporalContainer<Time>),
50	Duration(TemporalContainer<Duration>),
51	IdentityId(IdentityIdContainer),
52	Uuid4(UuidContainer<Uuid4>),
53	Uuid7(UuidContainer<Uuid7>),
54	Blob(BlobContainer),
55	Int(NumberContainer<Int>),
56	Uint(NumberContainer<Uint>),
57	Decimal(NumberContainer<Decimal>),
58	Any(AnyContainer),
59	DictionaryId(DictionaryContainer),
60	// nullable wrapper
61	Option {
62		inner: Box<FrameColumnData>,
63		bitvec: BitVec,
64	},
65}
66
67impl FrameColumnData {
68	pub fn get_type(&self) -> Type {
69		match self {
70			FrameColumnData::Bool(_) => Type::Boolean,
71			FrameColumnData::Float4(_) => Type::Float4,
72			FrameColumnData::Float8(_) => Type::Float8,
73			FrameColumnData::Int1(_) => Type::Int1,
74			FrameColumnData::Int2(_) => Type::Int2,
75			FrameColumnData::Int4(_) => Type::Int4,
76			FrameColumnData::Int8(_) => Type::Int8,
77			FrameColumnData::Int16(_) => Type::Int16,
78			FrameColumnData::Uint1(_) => Type::Uint1,
79			FrameColumnData::Uint2(_) => Type::Uint2,
80			FrameColumnData::Uint4(_) => Type::Uint4,
81			FrameColumnData::Uint8(_) => Type::Uint8,
82			FrameColumnData::Uint16(_) => Type::Uint16,
83			FrameColumnData::Utf8(_) => Type::Utf8,
84			FrameColumnData::Date(_) => Type::Date,
85			FrameColumnData::DateTime(_) => Type::DateTime,
86			FrameColumnData::Time(_) => Type::Time,
87			FrameColumnData::Duration(_) => Type::Duration,
88			FrameColumnData::IdentityId(_) => Type::IdentityId,
89			FrameColumnData::Uuid4(_) => Type::Uuid4,
90			FrameColumnData::Uuid7(_) => Type::Uuid7,
91			FrameColumnData::Blob(_) => Type::Blob,
92			FrameColumnData::Int(_) => Type::Int,
93			FrameColumnData::Uint(_) => Type::Uint,
94			FrameColumnData::Decimal(_) => Type::Decimal,
95			FrameColumnData::Any(_) => Type::Any,
96			FrameColumnData::DictionaryId(_) => Type::DictionaryId,
97			FrameColumnData::Option {
98				inner,
99				..
100			} => Type::Option(Box::new(inner.get_type())),
101		}
102	}
103
104	pub fn is_defined(&self, idx: usize) -> bool {
105		match self {
106			FrameColumnData::Bool(container) => container.is_defined(idx),
107			FrameColumnData::Float4(container) => container.is_defined(idx),
108			FrameColumnData::Float8(container) => container.is_defined(idx),
109			FrameColumnData::Int1(container) => container.is_defined(idx),
110			FrameColumnData::Int2(container) => container.is_defined(idx),
111			FrameColumnData::Int4(container) => container.is_defined(idx),
112			FrameColumnData::Int8(container) => container.is_defined(idx),
113			FrameColumnData::Int16(container) => container.is_defined(idx),
114			FrameColumnData::Uint1(container) => container.is_defined(idx),
115			FrameColumnData::Uint2(container) => container.is_defined(idx),
116			FrameColumnData::Uint4(container) => container.is_defined(idx),
117			FrameColumnData::Uint8(container) => container.is_defined(idx),
118			FrameColumnData::Uint16(container) => container.is_defined(idx),
119			FrameColumnData::Utf8(container) => container.is_defined(idx),
120			FrameColumnData::Date(container) => container.is_defined(idx),
121			FrameColumnData::DateTime(container) => container.is_defined(idx),
122			FrameColumnData::Time(container) => container.is_defined(idx),
123			FrameColumnData::Duration(container) => container.is_defined(idx),
124			FrameColumnData::IdentityId(container) => container.is_defined(idx),
125			FrameColumnData::Uuid4(container) => container.is_defined(idx),
126			FrameColumnData::Uuid7(container) => container.is_defined(idx),
127			FrameColumnData::Blob(container) => container.is_defined(idx),
128			FrameColumnData::Int(container) => container.is_defined(idx),
129			FrameColumnData::Uint(container) => container.is_defined(idx),
130			FrameColumnData::Decimal(container) => container.is_defined(idx),
131			FrameColumnData::Any(container) => container.is_defined(idx),
132			FrameColumnData::DictionaryId(container) => container.is_defined(idx),
133			FrameColumnData::Option {
134				bitvec,
135				..
136			} => idx < DataBitVec::len(bitvec) && DataBitVec::get(bitvec, idx),
137		}
138	}
139
140	pub fn is_bool(&self) -> bool {
141		self.get_type() == Type::Boolean
142	}
143
144	pub fn is_float(&self) -> bool {
145		self.get_type() == Type::Float4 || self.get_type() == Type::Float8
146	}
147
148	pub fn is_utf8(&self) -> bool {
149		self.get_type() == Type::Utf8
150	}
151
152	pub fn is_number(&self) -> bool {
153		matches!(
154			self.get_type(),
155			Type::Float4
156				| Type::Float8 | Type::Int1 | Type::Int2
157				| Type::Int4 | Type::Int8 | Type::Int16
158				| Type::Uint1 | Type::Uint2 | Type::Uint4
159				| Type::Uint8 | Type::Uint16
160		)
161	}
162
163	pub fn is_text(&self) -> bool {
164		self.get_type() == Type::Utf8
165	}
166
167	pub fn is_temporal(&self) -> bool {
168		matches!(self.get_type(), Type::Date | Type::DateTime | Type::Time | Type::Duration)
169	}
170
171	pub fn is_uuid(&self) -> bool {
172		matches!(self.get_type(), Type::Uuid4 | Type::Uuid7)
173	}
174
175	pub fn iter<'a>(&'a self) -> Box<dyn Iterator<Item = Value> + 'a> {
176		Box::new((0..self.len()).map(move |i| self.get_value(i)))
177	}
178}
179
180impl FrameColumnData {
181	pub fn len(&self) -> usize {
182		match self {
183			FrameColumnData::Bool(container) => container.len(),
184			FrameColumnData::Float4(container) => container.len(),
185			FrameColumnData::Float8(container) => container.len(),
186			FrameColumnData::Int1(container) => container.len(),
187			FrameColumnData::Int2(container) => container.len(),
188			FrameColumnData::Int4(container) => container.len(),
189			FrameColumnData::Int8(container) => container.len(),
190			FrameColumnData::Int16(container) => container.len(),
191			FrameColumnData::Uint1(container) => container.len(),
192			FrameColumnData::Uint2(container) => container.len(),
193			FrameColumnData::Uint4(container) => container.len(),
194			FrameColumnData::Uint8(container) => container.len(),
195			FrameColumnData::Uint16(container) => container.len(),
196			FrameColumnData::Utf8(container) => container.len(),
197			FrameColumnData::Date(container) => container.len(),
198			FrameColumnData::DateTime(container) => container.len(),
199			FrameColumnData::Time(container) => container.len(),
200			FrameColumnData::Duration(container) => container.len(),
201			FrameColumnData::IdentityId(container) => container.len(),
202			FrameColumnData::Uuid4(container) => container.len(),
203			FrameColumnData::Uuid7(container) => container.len(),
204			FrameColumnData::Blob(container) => container.len(),
205			FrameColumnData::Int(container) => container.len(),
206			FrameColumnData::Uint(container) => container.len(),
207			FrameColumnData::Decimal(container) => container.len(),
208			FrameColumnData::Any(container) => container.len(),
209			FrameColumnData::DictionaryId(container) => container.len(),
210			FrameColumnData::Option {
211				inner,
212				..
213			} => inner.len(),
214		}
215	}
216
217	pub fn as_string(&self, index: usize) -> String {
218		match self {
219			FrameColumnData::Bool(container) => container.as_string(index),
220			FrameColumnData::Float4(container) => {
221				if let Some(&v) = container.get(index) {
222					format_f32(v)
223				} else {
224					"none".to_string()
225				}
226			}
227			FrameColumnData::Float8(container) => {
228				if let Some(&v) = container.get(index) {
229					format_f64(v)
230				} else {
231					"none".to_string()
232				}
233			}
234			FrameColumnData::Int1(container) => container.as_string(index),
235			FrameColumnData::Int2(container) => container.as_string(index),
236			FrameColumnData::Int4(container) => container.as_string(index),
237			FrameColumnData::Int8(container) => container.as_string(index),
238			FrameColumnData::Int16(container) => container.as_string(index),
239			FrameColumnData::Uint1(container) => container.as_string(index),
240			FrameColumnData::Uint2(container) => container.as_string(index),
241			FrameColumnData::Uint4(container) => container.as_string(index),
242			FrameColumnData::Uint8(container) => container.as_string(index),
243			FrameColumnData::Uint16(container) => container.as_string(index),
244			FrameColumnData::Utf8(container) => container.as_string(index),
245			FrameColumnData::Date(container) => container.as_string(index),
246			FrameColumnData::DateTime(container) => container.as_string(index),
247			FrameColumnData::Time(container) => container.as_string(index),
248			FrameColumnData::Duration(container) => container.as_string(index),
249			FrameColumnData::IdentityId(container) => container.as_string(index),
250			FrameColumnData::Uuid4(container) => container.as_string(index),
251			FrameColumnData::Uuid7(container) => container.as_string(index),
252			FrameColumnData::Blob(container) => container.as_string(index),
253			FrameColumnData::Int(container) => container.as_string(index),
254			FrameColumnData::Uint(container) => container.as_string(index),
255			FrameColumnData::Decimal(container) => container.as_string(index),
256			FrameColumnData::Any(container) => container.as_string(index),
257			FrameColumnData::DictionaryId(container) => container.as_string(index),
258			FrameColumnData::Option {
259				inner,
260				bitvec,
261			} => {
262				if DataBitVec::get(bitvec, index) {
263					inner.as_string(index)
264				} else {
265					"none".to_string()
266				}
267			}
268		}
269	}
270}
271
272impl FrameColumnData {
273	pub fn get_value(&self, index: usize) -> Value {
274		match self {
275			FrameColumnData::Bool(container) => container.get_value(index),
276			FrameColumnData::Float4(container) => container.get_value(index),
277			FrameColumnData::Float8(container) => container.get_value(index),
278			FrameColumnData::Int1(container) => container.get_value(index),
279			FrameColumnData::Int2(container) => container.get_value(index),
280			FrameColumnData::Int4(container) => container.get_value(index),
281			FrameColumnData::Int8(container) => container.get_value(index),
282			FrameColumnData::Int16(container) => container.get_value(index),
283			FrameColumnData::Uint1(container) => container.get_value(index),
284			FrameColumnData::Uint2(container) => container.get_value(index),
285			FrameColumnData::Uint4(container) => container.get_value(index),
286			FrameColumnData::Uint8(container) => container.get_value(index),
287			FrameColumnData::Uint16(container) => container.get_value(index),
288			FrameColumnData::Utf8(container) => container.get_value(index),
289			FrameColumnData::Date(container) => container.get_value(index),
290			FrameColumnData::DateTime(container) => container.get_value(index),
291			FrameColumnData::Time(container) => container.get_value(index),
292			FrameColumnData::Duration(container) => container.get_value(index),
293			FrameColumnData::IdentityId(container) => container.get_value(index),
294			FrameColumnData::Uuid4(container) => container.get_value(index),
295			FrameColumnData::Uuid7(container) => container.get_value(index),
296			FrameColumnData::Blob(container) => container.get_value(index),
297			FrameColumnData::Int(container) => container.get_value(index),
298			FrameColumnData::Uint(container) => container.get_value(index),
299			FrameColumnData::Decimal(container) => container.get_value(index),
300			FrameColumnData::Any(container) => container.get_value(index),
301			FrameColumnData::DictionaryId(container) => container.get_value(index),
302			FrameColumnData::Option {
303				inner,
304				bitvec,
305			} => {
306				if DataBitVec::get(bitvec, index) {
307					inner.get_value(index)
308				} else {
309					Value::none_of(inner.get_type())
310				}
311			}
312		}
313	}
314}