Skip to main content

reifydb_core/value/column/
row_ref.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use reifydb_type::value::{Value, decimal::Decimal, row_number::RowNumber};
5
6use crate::value::column::columns::Columns;
7
8#[derive(Clone, Copy)]
9pub struct RowRef<'a> {
10	columns: &'a Columns,
11	index: usize,
12}
13
14impl<'a> RowRef<'a> {
15	pub(crate) fn new(columns: &'a Columns, index: usize) -> Self {
16		Self {
17			columns,
18			index,
19		}
20	}
21
22	pub fn index(&self) -> usize {
23		self.index
24	}
25
26	pub fn row_number(&self) -> Option<RowNumber> {
27		self.columns.row_numbers.get(self.index).copied()
28	}
29
30	pub fn value(&self, name: &str) -> Option<Value> {
31		let col = self.columns.column(name)?;
32		Some(col.data().get_value(self.index))
33	}
34
35	pub fn is_defined(&self, name: &str) -> bool {
36		match self.value(name) {
37			Some(Value::None {
38				..
39			}) => false,
40			Some(_) => true,
41			None => false,
42		}
43	}
44
45	pub fn utf8(&self, name: &str) -> Option<String> {
46		match self.value(name)? {
47			Value::Utf8(s) => Some(s),
48			_ => None,
49		}
50	}
51
52	pub fn bool(&self, name: &str) -> Option<bool> {
53		match self.value(name)? {
54			Value::Boolean(b) => Some(b),
55			_ => None,
56		}
57	}
58
59	pub fn u64(&self, name: &str) -> Option<u64> {
60		match self.value(name)? {
61			Value::Uint8(v) => Some(v),
62			Value::Uint4(v) => Some(v as u64),
63			Value::Uint2(v) => Some(v as u64),
64			Value::Uint1(v) => Some(v as u64),
65			_ => None,
66		}
67	}
68
69	pub fn u32(&self, name: &str) -> Option<u32> {
70		match self.value(name)? {
71			Value::Uint4(v) => Some(v),
72			Value::Uint2(v) => Some(v as u32),
73			Value::Uint1(v) => Some(v as u32),
74			_ => None,
75		}
76	}
77
78	pub fn u16(&self, name: &str) -> Option<u16> {
79		match self.value(name)? {
80			Value::Uint2(v) => Some(v),
81			Value::Uint1(v) => Some(v as u16),
82			_ => None,
83		}
84	}
85
86	pub fn u8(&self, name: &str) -> Option<u8> {
87		match self.value(name)? {
88			Value::Uint1(v) => Some(v),
89			_ => None,
90		}
91	}
92
93	pub fn i64(&self, name: &str) -> Option<i64> {
94		match self.value(name)? {
95			Value::Int8(v) => Some(v),
96			Value::Int4(v) => Some(v as i64),
97			Value::Int2(v) => Some(v as i64),
98			Value::Int1(v) => Some(v as i64),
99			_ => None,
100		}
101	}
102
103	pub fn i32(&self, name: &str) -> Option<i32> {
104		match self.value(name)? {
105			Value::Int4(v) => Some(v),
106			Value::Int2(v) => Some(v as i32),
107			Value::Int1(v) => Some(v as i32),
108			_ => None,
109		}
110	}
111
112	pub fn i16(&self, name: &str) -> Option<i16> {
113		match self.value(name)? {
114			Value::Int2(v) => Some(v),
115			Value::Int1(v) => Some(v as i16),
116			_ => None,
117		}
118	}
119
120	pub fn i8(&self, name: &str) -> Option<i8> {
121		match self.value(name)? {
122			Value::Int1(v) => Some(v),
123			_ => None,
124		}
125	}
126
127	pub fn u128(&self, name: &str) -> Option<u128> {
128		match self.value(name)? {
129			Value::Uint16(v) => Some(v),
130			_ => None,
131		}
132	}
133
134	pub fn i128(&self, name: &str) -> Option<i128> {
135		match self.value(name)? {
136			Value::Int16(v) => Some(v),
137			_ => None,
138		}
139	}
140
141	pub fn f64(&self, name: &str) -> Option<f64> {
142		match self.value(name)? {
143			Value::Float8(v) => Some(v.into()),
144			Value::Float4(v) => Some(f32::from(v) as f64),
145			_ => None,
146		}
147	}
148
149	pub fn f32(&self, name: &str) -> Option<f32> {
150		match self.value(name)? {
151			Value::Float4(v) => Some(v.into()),
152			_ => None,
153		}
154	}
155
156	pub fn decimal(&self, name: &str) -> Option<Decimal> {
157		match self.value(name)? {
158			Value::Decimal(v) => Some(v),
159			Value::Float8(v) => Some(Decimal::from(f64::from(v))),
160			Value::Float4(v) => Some(Decimal::from(f32::from(v) as f64)),
161			_ => None,
162		}
163	}
164
165	pub fn blob(&self, name: &str) -> Option<Vec<u8>> {
166		match self.value(name)? {
167			Value::Blob(b) => Some(b.as_bytes().to_vec()),
168			_ => None,
169		}
170	}
171}
172
173pub struct RowRefIter<'a> {
174	columns: &'a Columns,
175	index: usize,
176	end: usize,
177}
178
179impl<'a> Iterator for RowRefIter<'a> {
180	type Item = RowRef<'a>;
181
182	fn next(&mut self) -> Option<Self::Item> {
183		if self.index >= self.end {
184			return None;
185		}
186		let r = RowRef::new(self.columns, self.index);
187		self.index += 1;
188		Some(r)
189	}
190}
191
192impl Columns {
193	pub fn row_ref(&self, index: usize) -> Option<RowRef<'_>> {
194		if index >= self.row_count() {
195			return None;
196		}
197		Some(RowRef::new(self, index))
198	}
199
200	pub fn row_refs(&self) -> RowRefIter<'_> {
201		RowRefIter {
202			columns: self,
203			index: 0,
204			end: self.row_count(),
205		}
206	}
207}