reifydb_core/value/column/push/
mod.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the AGPL-3.0-or-later, see license.md file
3
4use std::fmt::Debug;
5
6use reifydb_type::{Blob, Date, DateTime, Duration, Time};
7
8use crate::value::column::ColumnData;
9
10mod decimal;
11mod i128;
12mod i16;
13mod i32;
14mod i64;
15mod i8;
16mod int;
17mod u128;
18mod u16;
19mod u32;
20mod u64;
21mod u8;
22mod uint;
23mod undefined;
24mod uuid;
25mod value;
26
27pub trait Push<T> {
28	fn push(&mut self, value: T);
29}
30
31impl ColumnData {
32	pub fn push<T>(&mut self, value: T)
33	where
34		Self: Push<T>,
35		T: Debug,
36	{
37		<Self as Push<T>>::push(self, value)
38	}
39}
40
41macro_rules! impl_push {
42	($t:ty, $variant:ident, $factory:ident) => {
43		impl Push<$t> for ColumnData {
44			fn push(&mut self, value: $t) {
45				match self {
46					ColumnData::$variant(container) => {
47						container.push(value);
48					}
49					ColumnData::Undefined(container) => {
50						let mut new_container =
51							ColumnData::$factory(vec![<$t>::default(); container.len()]);
52						if let ColumnData::$variant(new_container) = &mut new_container {
53							new_container.push(value);
54						}
55						*self = new_container;
56					}
57					other => panic!(
58						"called `push::<{}>()` on EngineColumnData::{:?}",
59						stringify!($t),
60						other.get_type()
61					),
62				}
63			}
64		}
65	};
66}
67
68impl Push<bool> for ColumnData {
69	fn push(&mut self, value: bool) {
70		match self {
71			ColumnData::Bool(container) => {
72				container.push(value);
73			}
74			ColumnData::Undefined(container) => {
75				let mut new_container = ColumnData::bool(vec![false; container.len()]);
76				if let ColumnData::Bool(new_container) = &mut new_container {
77					new_container.push(value);
78				}
79				*self = new_container;
80			}
81			other => panic!("called `push::<bool>()` on EngineColumnData::{:?}", other.get_type()),
82		}
83	}
84}
85
86impl_push!(f32, Float4, float4);
87impl_push!(f64, Float8, float8);
88impl_push!(Date, Date, date);
89impl_push!(DateTime, DateTime, datetime);
90impl_push!(Time, Time, time);
91impl_push!(Duration, Duration, duration);
92
93impl Push<Blob> for ColumnData {
94	fn push(&mut self, value: Blob) {
95		match self {
96			ColumnData::Blob {
97				container,
98				..
99			} => {
100				container.push(value);
101			}
102			ColumnData::Undefined(container) => {
103				let mut new_container = ColumnData::blob(vec![Blob::default(); container.len()]);
104				if let ColumnData::Blob {
105					container: new_container,
106					..
107				} = &mut new_container
108				{
109					new_container.push(value);
110				}
111				*self = new_container;
112			}
113			other => panic!("called `push::<Blob>()` on EngineColumnData::{:?}", other.get_type()),
114		}
115	}
116}
117
118impl Push<String> for ColumnData {
119	fn push(&mut self, value: String) {
120		match self {
121			ColumnData::Utf8 {
122				container,
123				..
124			} => {
125				container.push(value);
126			}
127			ColumnData::Undefined(container) => {
128				let mut new_container = ColumnData::utf8(vec![String::default(); container.len()]);
129				if let ColumnData::Utf8 {
130					container: new_container,
131					..
132				} = &mut new_container
133				{
134					new_container.push(value);
135				}
136				*self = new_container;
137			}
138			other => {
139				panic!("called `push::<String>()` on EngineColumnData::{:?}", other.get_type())
140			}
141		}
142	}
143}
144
145impl Push<&str> for ColumnData {
146	fn push(&mut self, value: &str) {
147		self.push(value.to_string());
148	}
149}