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 f64(&self, name: &str) -> Option<f64> {
128		match self.value(name)? {
129			Value::Float8(v) => Some(v.into()),
130			Value::Float4(v) => Some(f32::from(v) as f64),
131			_ => None,
132		}
133	}
134
135	pub fn f32(&self, name: &str) -> Option<f32> {
136		match self.value(name)? {
137			Value::Float4(v) => Some(v.into()),
138			_ => None,
139		}
140	}
141
142	pub fn decimal(&self, name: &str) -> Option<Decimal> {
143		match self.value(name)? {
144			Value::Decimal(v) => Some(v),
145			Value::Float8(v) => Some(Decimal::from(f64::from(v))),
146			Value::Float4(v) => Some(Decimal::from(f32::from(v) as f64)),
147			_ => None,
148		}
149	}
150
151	pub fn blob(&self, name: &str) -> Option<Vec<u8>> {
152		match self.value(name)? {
153			Value::Blob(b) => Some(b.as_bytes().to_vec()),
154			_ => None,
155		}
156	}
157}
158
159pub struct RowRefIter<'a> {
160	columns: &'a Columns,
161	index: usize,
162	end: usize,
163}
164
165impl<'a> Iterator for RowRefIter<'a> {
166	type Item = RowRef<'a>;
167
168	fn next(&mut self) -> Option<Self::Item> {
169		if self.index >= self.end {
170			return None;
171		}
172		let r = RowRef::new(self.columns, self.index);
173		self.index += 1;
174		Some(r)
175	}
176}
177
178impl Columns {
179	pub fn row_ref(&self, index: usize) -> Option<RowRef<'_>> {
180		if index >= self.row_count() {
181			return None;
182		}
183		Some(RowRef::new(self, index))
184	}
185
186	pub fn row_refs(&self) -> RowRefIter<'_> {
187		RowRefIter {
188			columns: self,
189			index: 0,
190			end: self.row_count(),
191		}
192	}
193}