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 reifydb_value::value::{
5	blob::Blob,
6	container::{
7		dictionary_array,
8		temporal_array::{date_to_native, datetime_to_native, duration_to_native, time_to_native},
9	},
10	date::Date,
11	datetime::DateTime,
12	dictionary::DictionaryEntryId,
13	duration::Duration,
14	number::safe::convert::SafeConvert,
15	ordered_f32::OrderedF32,
16	ordered_f64::OrderedF64,
17	time::Time,
18};
19
20use crate::value::column::builder::{ColumnBuilder, TypedBuilder, append_fixed};
21
22pub mod decimal;
23pub mod none;
24pub mod typed;
25pub mod uuid;
26pub mod value;
27
28pub trait Push<T> {
29	fn push(&mut self, value: T);
30}
31
32macro_rules! impl_native_push {
33	($t:ty, $variant:ident, $canonical:expr) => {
34		impl Push<$t> for ColumnBuilder {
35			fn push(&mut self, value: $t) {
36				match &mut self.inner {
37					TypedBuilder::$variant(builder) => {
38						builder.append_value($canonical(value));
39					}
40					other => panic!(
41						"called `push::<{}>()` on ColumnBuilder::{:?}",
42						stringify!($t),
43						other.get_type()
44					),
45				}
46			}
47		}
48	};
49}
50
51macro_rules! impl_temporal_push {
52	($t:ty, $variant:ident, $to_native:ident) => {
53		impl Push<$t> for ColumnBuilder {
54			fn push(&mut self, value: $t) {
55				match &mut self.inner {
56					TypedBuilder::$variant(builder) => {
57						builder.append_value($to_native(value));
58					}
59					other => panic!(
60						"called `push::<{}>()` on ColumnBuilder::{:?}",
61						stringify!($t),
62						other.get_type()
63					),
64				}
65			}
66		}
67	};
68}
69
70macro_rules! impl_numeric_push {
71	($from:ty,
72		$own:ident,
73		native [$(($variant:ident, $target:ty)),* $(,)?]
74	) => {
75		impl Push<$from> for ColumnBuilder {
76			fn push(&mut self, value: $from) {
77				match &mut self.inner {
78					$(
79						TypedBuilder::$variant(builder) => {
80							builder.append_value(<$from as SafeConvert<$target>>::saturating_convert(value));
81						},
82					)*
83					TypedBuilder::$own(builder) => {
84						builder.append_value(value);
85					}
86					other => {
87						panic!(
88							"called `push::<{}>()` on incompatible ColumnBuilder::{:?}",
89							stringify!($from),
90							other.get_type()
91						);
92					}
93				}
94			}
95		}
96	};
97}
98
99impl Push<bool> for ColumnBuilder {
100	fn push(&mut self, value: bool) {
101		match &mut self.inner {
102			TypedBuilder::Bool(builder) => builder.append_value(value),
103			other => panic!("called `push::<bool>()` on ColumnBuilder::{:?}", other.get_type()),
104		}
105	}
106}
107
108impl_native_push!(f32, Float4, OrderedF32::canonical);
109impl_native_push!(f64, Float8, OrderedF64::canonical);
110impl_temporal_push!(Date, Date, date_to_native);
111impl_temporal_push!(DateTime, DateTime, datetime_to_native);
112impl_temporal_push!(Time, Time, time_to_native);
113impl_temporal_push!(Duration, Duration, duration_to_native);
114
115impl_numeric_push!(
116	i8,
117	Int1,
118	native [(Float4, f32), (Float8, f64), (Int2, i16), (Int4, i32), (Int8, i64), (Uint1, u8), (Uint2, u16), (Uint4, u32), (Uint8, u64), (Int16, i128), (Uint16, u128)]
119);
120
121impl_numeric_push!(
122	i16,
123	Int2,
124	native [(Float4, f32), (Float8, f64), (Int1, i8), (Int4, i32), (Int8, i64), (Uint1, u8), (Uint2, u16), (Uint4, u32), (Uint8, u64), (Int16, i128), (Uint16, u128)]
125);
126
127impl_numeric_push!(
128	i32,
129	Int4,
130	native [(Float4, f32), (Float8, f64), (Int1, i8), (Int2, i16), (Int8, i64), (Uint1, u8), (Uint2, u16), (Uint4, u32), (Uint8, u64), (Int16, i128), (Uint16, u128)]
131);
132
133impl_numeric_push!(
134	i64,
135	Int8,
136	native [(Float4, f32), (Float8, f64), (Int1, i8), (Int2, i16), (Int4, i32), (Uint1, u8), (Uint2, u16), (Uint4, u32), (Uint8, u64), (Int16, i128), (Uint16, u128)]
137);
138
139impl_numeric_push!(
140	i128,
141	Int16,
142	native [(Float4, f32), (Float8, f64), (Int1, i8), (Int2, i16), (Int4, i32), (Int8, i64), (Uint1, u8), (Uint2, u16), (Uint4, u32), (Uint8, u64), (Uint16, u128)]
143);
144
145impl_numeric_push!(
146	u8,
147	Uint1,
148	native [(Float4, f32), (Float8, f64), (Uint2, u16), (Uint4, u32), (Uint8, u64), (Int1, i8), (Int2, i16), (Int4, i32), (Int8, i64), (Int16, i128), (Uint16, u128)]
149);
150
151impl_numeric_push!(
152	u16,
153	Uint2,
154	native [(Float4, f32), (Float8, f64), (Uint1, u8), (Uint4, u32), (Uint8, u64), (Int1, i8), (Int2, i16), (Int4, i32), (Int8, i64), (Int16, i128), (Uint16, u128)]
155);
156
157impl_numeric_push!(
158	u32,
159	Uint4,
160	native [(Float4, f32), (Float8, f64), (Uint1, u8), (Uint2, u16), (Uint8, u64), (Int1, i8), (Int2, i16), (Int4, i32), (Int8, i64), (Int16, i128), (Uint16, u128)]
161);
162
163impl_numeric_push!(
164	u64,
165	Uint8,
166	native [(Float4, f32), (Float8, f64), (Uint1, u8), (Uint2, u16), (Uint4, u32), (Int1, i8), (Int2, i16), (Int4, i32), (Int8, i64), (Int16, i128), (Uint16, u128)]
167);
168
169impl_numeric_push!(
170	u128,
171	Uint16,
172	native [(Float4, f32), (Float8, f64), (Uint1, u8), (Uint2, u16), (Uint4, u32), (Uint8, u64), (Int1, i8), (Int2, i16), (Int4, i32), (Int8, i64), (Int16, i128)]
173);
174
175impl Push<Blob> for ColumnBuilder {
176	fn push(&mut self, value: Blob) {
177		match &mut self.inner {
178			TypedBuilder::Blob {
179				builder,
180				..
181			} => {
182				builder.append_value(value.as_bytes());
183			}
184			other => panic!("called `push::<Blob>()` on ColumnBuilder::{:?}", other.get_type()),
185		}
186	}
187}
188
189impl Push<String> for ColumnBuilder {
190	fn push(&mut self, value: String) {
191		match &mut self.inner {
192			TypedBuilder::Utf8 {
193				builder,
194				..
195			} => {
196				builder.append_value(value);
197			}
198			other => {
199				panic!("called `push::<String>()` on ColumnBuilder::{:?}", other.get_type())
200			}
201		}
202	}
203}
204
205impl Push<DictionaryEntryId> for ColumnBuilder {
206	fn push(&mut self, value: DictionaryEntryId) {
207		match &mut self.inner {
208			TypedBuilder::DictionaryId {
209				builder,
210				..
211			} => append_fixed(builder, &dictionary_array::encode(value)),
212			other => {
213				panic!("called `push::<DictionaryEntryId>()` on ColumnBuilder::{:?}", other.get_type())
214			}
215		}
216	}
217}
218
219impl Push<&str> for ColumnBuilder {
220	fn push(&mut self, value: &str) {
221		self.push(value.to_string());
222	}
223}