Skip to main content

reifydb_core/value/column/push/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4//! Typed `Push<T>` trait and its blanket implementations for every primitive `ColumnBuffer` accepts.
5//!
6//! Each submodule (`int`, `uint`, `decimal`, `none`, `uuid`, `value`) implements `Push<T>` for the variants of
7//! `ColumnBuffer` that store `T`. Pushing a value of the wrong type panics rather than silently coercing; correctness
8//! at the column boundary is enforced by the type system at the call site, so a panic here is a planner bug, not a user
9//! error.
10
11use std::fmt::Debug;
12
13use reifydb_type::{
14	storage::DataBitVec,
15	value::{
16		blob::Blob, date::Date, datetime::DateTime, dictionary::DictionaryEntryId, duration::Duration,
17		number::safe::convert::SafeConvert, time::Time,
18	},
19};
20
21use crate::value::column::ColumnBuffer;
22
23pub mod decimal;
24pub mod int;
25pub mod none;
26pub mod uint;
27pub mod uuid;
28pub mod value;
29
30pub trait Push<T> {
31	fn push(&mut self, value: T);
32}
33
34impl ColumnBuffer {
35	pub fn push<T>(&mut self, value: T)
36	where
37		Self: Push<T>,
38		T: Debug,
39	{
40		<Self as Push<T>>::push(self, value)
41	}
42}
43
44macro_rules! impl_push {
45	($t:ty, $variant:ident, $factory:ident) => {
46		impl Push<$t> for ColumnBuffer {
47			fn push(&mut self, value: $t) {
48				match self {
49					ColumnBuffer::$variant(container) => {
50						container.push(value);
51					}
52					ColumnBuffer::Option {
53						inner,
54						bitvec,
55					} => {
56						inner.push(value);
57						DataBitVec::push(bitvec, true);
58					}
59					other => panic!(
60						"called `push::<{}>()` on ColumnBuffer::{:?}",
61						stringify!($t),
62						other.get_type()
63					),
64				}
65			}
66		}
67	};
68}
69
70macro_rules! impl_numeric_push {
71	($from:ty, $native_variant:ident, $factory:ident, $default:expr, [$(($variant:ident, $target:ty)),* $(,)?]) => {
72		impl Push<$from> for ColumnBuffer {
73			fn push(&mut self, value: $from) {
74				match self {
75					$(
76						ColumnBuffer::$variant(container) => match <$from as SafeConvert<$target>>::checked_convert(value) {
77							Some(v) => container.push(v),
78							None => container.push_default(),
79						},
80					)*
81					ColumnBuffer::$native_variant(container) => {
82						container.push(value);
83					}
84					ColumnBuffer::Option { inner, bitvec } => {
85						inner.push(value);
86						DataBitVec::push(bitvec, true);
87					}
88					other => {
89						panic!(
90							"called `push::<{}>()` on incompatible ColumnBuffer::{:?}",
91							stringify!($from),
92							other.get_type()
93						);
94					}
95				}
96			}
97		}
98	};
99}
100
101impl Push<bool> for ColumnBuffer {
102	fn push(&mut self, value: bool) {
103		match self {
104			ColumnBuffer::Bool(container) => {
105				container.push(value);
106			}
107			ColumnBuffer::Option {
108				inner,
109				bitvec,
110			} => {
111				inner.push(value);
112				DataBitVec::push(bitvec, true);
113			}
114			other => panic!("called `push::<bool>()` on ColumnBuffer::{:?}", other.get_type()),
115		}
116	}
117}
118
119impl_push!(f32, Float4, float4);
120impl_push!(f64, Float8, float8);
121impl_push!(Date, Date, date);
122impl_push!(DateTime, DateTime, datetime);
123impl_push!(Time, Time, time);
124impl_push!(Duration, Duration, duration);
125
126impl_numeric_push!(
127	i8,
128	Int1,
129	int1,
130	0i8,
131	[
132		(Float4, f32),
133		(Float8, f64),
134		(Int2, i16),
135		(Int4, i32),
136		(Int8, i64),
137		(Int16, i128),
138		(Uint1, u8),
139		(Uint2, u16),
140		(Uint4, u32),
141		(Uint8, u64),
142		(Uint16, u128),
143	]
144);
145
146impl_numeric_push!(
147	i16,
148	Int2,
149	int2,
150	0i16,
151	[
152		(Float4, f32),
153		(Float8, f64),
154		(Int1, i8),
155		(Int4, i32),
156		(Int8, i64),
157		(Int16, i128),
158		(Uint1, u8),
159		(Uint2, u16),
160		(Uint4, u32),
161		(Uint8, u64),
162		(Uint16, u128),
163	]
164);
165
166impl_numeric_push!(
167	i32,
168	Int4,
169	int4,
170	0i32,
171	[
172		(Float4, f32),
173		(Float8, f64),
174		(Int1, i8),
175		(Int2, i16),
176		(Int8, i64),
177		(Int16, i128),
178		(Uint1, u8),
179		(Uint2, u16),
180		(Uint4, u32),
181		(Uint8, u64),
182		(Uint16, u128),
183	]
184);
185
186impl_numeric_push!(
187	i64,
188	Int8,
189	int8,
190	0i64,
191	[
192		(Float4, f32),
193		(Float8, f64),
194		(Int1, i8),
195		(Int2, i16),
196		(Int4, i32),
197		(Int16, i128),
198		(Uint1, u8),
199		(Uint2, u16),
200		(Uint4, u32),
201		(Uint8, u64),
202		(Uint16, u128),
203	]
204);
205
206impl_numeric_push!(
207	i128,
208	Int16,
209	int16,
210	0i128,
211	[
212		(Float4, f32),
213		(Float8, f64),
214		(Int1, i8),
215		(Int2, i16),
216		(Int4, i32),
217		(Int8, i64),
218		(Uint1, u8),
219		(Uint2, u16),
220		(Uint4, u32),
221		(Uint8, u64),
222		(Uint16, u128),
223	]
224);
225
226impl_numeric_push!(
227	u8,
228	Uint1,
229	uint1,
230	0u8,
231	[
232		(Float4, f32),
233		(Float8, f64),
234		(Uint2, u16),
235		(Uint4, u32),
236		(Uint8, u64),
237		(Uint16, u128),
238		(Int1, i8),
239		(Int2, i16),
240		(Int4, i32),
241		(Int8, i64),
242		(Int16, i128),
243	]
244);
245
246impl_numeric_push!(
247	u16,
248	Uint2,
249	uint2,
250	0u16,
251	[
252		(Float4, f32),
253		(Float8, f64),
254		(Uint1, u8),
255		(Uint4, u32),
256		(Uint8, u64),
257		(Uint16, u128),
258		(Int1, i8),
259		(Int2, i16),
260		(Int4, i32),
261		(Int8, i64),
262		(Int16, i128),
263	]
264);
265
266impl_numeric_push!(
267	u32,
268	Uint4,
269	uint4,
270	0u32,
271	[
272		(Float4, f32),
273		(Float8, f64),
274		(Uint1, u8),
275		(Uint2, u16),
276		(Uint8, u64),
277		(Uint16, u128),
278		(Int1, i8),
279		(Int2, i16),
280		(Int4, i32),
281		(Int8, i64),
282		(Int16, i128),
283	]
284);
285
286impl_numeric_push!(
287	u64,
288	Uint8,
289	uint8,
290	0u64,
291	[
292		(Float4, f32),
293		(Float8, f64),
294		(Uint1, u8),
295		(Uint2, u16),
296		(Uint4, u32),
297		(Uint16, u128),
298		(Int1, i8),
299		(Int2, i16),
300		(Int4, i32),
301		(Int8, i64),
302		(Int16, i128),
303	]
304);
305
306impl_numeric_push!(
307	u128,
308	Uint16,
309	uint16,
310	0u128,
311	[
312		(Float4, f32),
313		(Float8, f64),
314		(Uint1, u8),
315		(Uint2, u16),
316		(Uint4, u32),
317		(Uint8, u64),
318		(Int1, i8),
319		(Int2, i16),
320		(Int4, i32),
321		(Int8, i64),
322		(Int16, i128),
323	]
324);
325
326impl Push<Blob> for ColumnBuffer {
327	fn push(&mut self, value: Blob) {
328		match self {
329			ColumnBuffer::Blob {
330				container,
331				..
332			} => {
333				container.push(value);
334			}
335			ColumnBuffer::Option {
336				inner,
337				bitvec,
338			} => {
339				inner.push(value);
340				DataBitVec::push(bitvec, true);
341			}
342			other => panic!("called `push::<Blob>()` on ColumnBuffer::{:?}", other.get_type()),
343		}
344	}
345}
346
347impl Push<String> for ColumnBuffer {
348	fn push(&mut self, value: String) {
349		match self {
350			ColumnBuffer::Utf8 {
351				container,
352				..
353			} => {
354				container.push(value);
355			}
356			ColumnBuffer::Option {
357				inner,
358				bitvec,
359			} => {
360				inner.push(value);
361				DataBitVec::push(bitvec, true);
362			}
363			other => {
364				panic!("called `push::<String>()` on ColumnBuffer::{:?}", other.get_type())
365			}
366		}
367	}
368}
369
370impl Push<DictionaryEntryId> for ColumnBuffer {
371	fn push(&mut self, value: DictionaryEntryId) {
372		match self {
373			ColumnBuffer::DictionaryId(container) => {
374				container.push(value);
375			}
376			ColumnBuffer::Option {
377				inner,
378				bitvec,
379			} => {
380				inner.push(value);
381				DataBitVec::push(bitvec, true);
382			}
383			other => panic!("called `push::<DictionaryEntryId>()` on ColumnBuffer::{:?}", other.get_type()),
384		}
385	}
386}
387
388impl Push<&str> for ColumnBuffer {
389	fn push(&mut self, value: &str) {
390		self.push(value.to_string());
391	}
392}