reifydb_type/value/
into.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the MIT, see license.md file
3
4use crate::{Blob, Date, DateTime, Duration, IdentityId, OrderedF32, OrderedF64, RowNumber, Time, Uuid4, Uuid7, Value};
5
6pub trait IntoValue {
7	fn into_value(self) -> Value;
8}
9
10impl IntoValue for Value {
11	fn into_value(self) -> Value {
12		self
13	}
14}
15
16impl IntoValue for bool {
17	fn into_value(self) -> Value {
18		Value::Boolean(self)
19	}
20}
21
22impl IntoValue for i8 {
23	fn into_value(self) -> Value {
24		Value::Int1(self)
25	}
26}
27
28impl IntoValue for i16 {
29	fn into_value(self) -> Value {
30		Value::Int2(self)
31	}
32}
33
34impl IntoValue for i32 {
35	fn into_value(self) -> Value {
36		Value::Int4(self)
37	}
38}
39
40impl IntoValue for i64 {
41	fn into_value(self) -> Value {
42		Value::Int8(self)
43	}
44}
45
46impl IntoValue for i128 {
47	fn into_value(self) -> Value {
48		Value::Int16(self)
49	}
50}
51
52impl IntoValue for u8 {
53	fn into_value(self) -> Value {
54		Value::Uint1(self)
55	}
56}
57
58impl IntoValue for u16 {
59	fn into_value(self) -> Value {
60		Value::Uint2(self)
61	}
62}
63
64impl IntoValue for u32 {
65	fn into_value(self) -> Value {
66		Value::Uint4(self)
67	}
68}
69
70impl IntoValue for u64 {
71	fn into_value(self) -> Value {
72		Value::Uint8(self)
73	}
74}
75
76impl IntoValue for u128 {
77	fn into_value(self) -> Value {
78		Value::Uint16(self)
79	}
80}
81
82impl IntoValue for f32 {
83	fn into_value(self) -> Value {
84		OrderedF32::try_from(self).map(|v| Value::Float4(v)).unwrap_or(Value::Undefined)
85	}
86}
87
88impl IntoValue for f64 {
89	fn into_value(self) -> Value {
90		OrderedF64::try_from(self).map(|v| Value::Float8(v)).unwrap_or(Value::Undefined)
91	}
92}
93
94impl IntoValue for String {
95	fn into_value(self) -> Value {
96		Value::Utf8(self)
97	}
98}
99
100impl IntoValue for &str {
101	fn into_value(self) -> Value {
102		Value::Utf8(self.to_string())
103	}
104}
105
106impl IntoValue for OrderedF32 {
107	fn into_value(self) -> Value {
108		Value::Float4(self)
109	}
110}
111
112impl IntoValue for OrderedF64 {
113	fn into_value(self) -> Value {
114		Value::Float8(self)
115	}
116}
117
118impl IntoValue for Blob {
119	fn into_value(self) -> Value {
120		Value::Blob(self)
121	}
122}
123
124impl IntoValue for Uuid4 {
125	fn into_value(self) -> Value {
126		Value::Uuid4(self)
127	}
128}
129
130impl IntoValue for Uuid7 {
131	fn into_value(self) -> Value {
132		Value::Uuid7(self)
133	}
134}
135
136impl IntoValue for Date {
137	fn into_value(self) -> Value {
138		Value::Date(self)
139	}
140}
141
142impl IntoValue for DateTime {
143	fn into_value(self) -> Value {
144		Value::DateTime(self)
145	}
146}
147
148impl IntoValue for Time {
149	fn into_value(self) -> Value {
150		Value::Time(self)
151	}
152}
153
154impl IntoValue for Duration {
155	fn into_value(self) -> Value {
156		Value::Duration(self)
157	}
158}
159
160impl IntoValue for RowNumber {
161	fn into_value(self) -> Value {
162		Value::RowNumber(self)
163	}
164}
165
166impl IntoValue for IdentityId {
167	fn into_value(self) -> Value {
168		Value::IdentityId(self)
169	}
170}
171
172impl<T: IntoValue> IntoValue for Option<T> {
173	fn into_value(self) -> Value {
174		match self {
175			Some(v) => v.into_value(),
176			None => Value::Undefined,
177		}
178	}
179}
180
181impl IntoValue for Vec<u8> {
182	fn into_value(self) -> Value {
183		Value::Blob(Blob::new(self))
184	}
185}
186
187impl IntoValue for &[u8] {
188	fn into_value(self) -> Value {
189		Value::Blob(Blob::from_slice(self))
190	}
191}
192
193impl<const N: usize> IntoValue for [u8; N] {
194	fn into_value(self) -> Value {
195		Value::Blob(Blob::from_slice(&self))
196	}
197}
198
199impl<const N: usize> IntoValue for &[u8; N] {
200	fn into_value(self) -> Value {
201		Value::Blob(Blob::from_slice(self))
202	}
203}
204
205#[cfg(test)]
206#[allow(clippy::approx_constant)]
207mod tests {
208	use std::f64::consts::PI;
209
210	use crate::{Blob, IntoValue, OrderedF32, OrderedF64, Value};
211
212	#[test]
213	fn test_into_value_primitives() {
214		// Test boolean
215		assert_eq!(true.into_value(), Value::Boolean(true));
216		assert_eq!(false.into_value(), Value::Boolean(false));
217
218		// Test integers
219		assert_eq!(42i8.into_value(), Value::Int1(42));
220		assert_eq!(1234i16.into_value(), Value::Int2(1234));
221		assert_eq!(123456i32.into_value(), Value::Int4(123456));
222		assert_eq!(1234567890i64.into_value(), Value::Int8(1234567890));
223		assert_eq!(12345678901234567890i128.into_value(), Value::Int16(12345678901234567890));
224
225		// Test unsigned integers
226		assert_eq!(42u8.into_value(), Value::Uint1(42));
227		assert_eq!(1234u16.into_value(), Value::Uint2(1234));
228		assert_eq!(123456u32.into_value(), Value::Uint4(123456));
229		assert_eq!(1234567890u64.into_value(), Value::Uint8(1234567890));
230		assert_eq!(12345678901234567890u128.into_value(), Value::Uint16(12345678901234567890));
231
232		// Test floats
233		assert_eq!(3.14f32.into_value(), Value::Float4(OrderedF32::try_from(3.14f32).unwrap()));
234		assert_eq!(PI.into_value(), Value::Float8(OrderedF64::try_from(PI).unwrap()));
235
236		// Test NaN handling
237
238		assert_eq!(f32::NAN.into_value(), Value::Undefined);
239		assert_eq!(f64::NAN.into_value(), Value::Undefined);
240	}
241
242	#[test]
243	fn test_into_value_strings() {
244		assert_eq!("hello".into_value(), Value::Utf8("hello".to_string()));
245		assert_eq!("world".to_string().into_value(), Value::Utf8("world".to_string()));
246	}
247
248	#[test]
249	fn test_into_value_option() {
250		assert_eq!(Some(42i32).into_value(), Value::Int4(42));
251		assert_eq!(None::<i32>.into_value(), Value::Undefined);
252		assert_eq!(Some("hello").into_value(), Value::Utf8("hello".to_string()));
253		assert_eq!(None::<&str>.into_value(), Value::Undefined);
254	}
255
256	#[test]
257	fn test_into_value_bytes() {
258		// Test Vec<u8>
259		let vec_bytes = vec![1u8, 2, 3, 4];
260		assert_eq!(vec_bytes.clone().into_value(), Value::Blob(Blob::new(vec![1, 2, 3, 4])));
261
262		// Test &[u8]
263		let slice_bytes: &[u8] = &[5, 6, 7, 8];
264		assert_eq!(slice_bytes.into_value(), Value::Blob(Blob::from_slice(&[5, 6, 7, 8])));
265
266		// Test [u8; N]
267		let array_bytes: [u8; 4] = [9, 10, 11, 12];
268		assert_eq!(array_bytes.into_value(), Value::Blob(Blob::from_slice(&[9, 10, 11, 12])));
269
270		// Test &[u8; N]
271		let array_ref: &[u8; 3] = &[13, 14, 15];
272		assert_eq!(array_ref.into_value(), Value::Blob(Blob::from_slice(&[13, 14, 15])));
273
274		// Test Vec<u8>
275		let vec = vec![16, 17, 18];
276		assert_eq!(vec.into_value(), Value::Blob(Blob::new(vec![16, 17, 18])));
277	}
278}