Skip to main content

reifydb_core/value/column/push/
mod.rs

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