Skip to main content

reifydb_value/value/frame/
data.rs

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