Skip to main content

reinhardt_query/value/
into_value.rs

1//! IntoValue trait and implementations.
2
3use super::Value;
4
5/// Trait for converting Rust types to SQL values.
6///
7/// This trait provides a uniform way to convert various Rust types
8/// into the [`Value`] enum used by the query builder.
9///
10/// # Example
11///
12/// ```rust
13/// use reinhardt_query::{IntoValue, Value};
14///
15/// let int_value: Value = 42i32.into_value();
16/// let str_value: Value = "hello".into_value();
17/// let null_value: Value = Option::<i32>::None.into_value();
18/// ```
19pub trait IntoValue {
20	/// Converts this value into a [`Value`].
21	fn into_value(self) -> Value;
22}
23
24// =============================================================================
25// Implementations for primitive types
26// =============================================================================
27
28impl IntoValue for bool {
29	fn into_value(self) -> Value {
30		Value::Bool(Some(self))
31	}
32}
33
34impl IntoValue for Option<bool> {
35	fn into_value(self) -> Value {
36		Value::Bool(self)
37	}
38}
39
40impl IntoValue for i8 {
41	fn into_value(self) -> Value {
42		Value::TinyInt(Some(self))
43	}
44}
45
46impl IntoValue for Option<i8> {
47	fn into_value(self) -> Value {
48		Value::TinyInt(self)
49	}
50}
51
52impl IntoValue for i16 {
53	fn into_value(self) -> Value {
54		Value::SmallInt(Some(self))
55	}
56}
57
58impl IntoValue for Option<i16> {
59	fn into_value(self) -> Value {
60		Value::SmallInt(self)
61	}
62}
63
64impl IntoValue for i32 {
65	fn into_value(self) -> Value {
66		Value::Int(Some(self))
67	}
68}
69
70impl IntoValue for Option<i32> {
71	fn into_value(self) -> Value {
72		Value::Int(self)
73	}
74}
75
76impl IntoValue for i64 {
77	fn into_value(self) -> Value {
78		Value::BigInt(Some(self))
79	}
80}
81
82impl IntoValue for Option<i64> {
83	fn into_value(self) -> Value {
84		Value::BigInt(self)
85	}
86}
87
88impl IntoValue for u8 {
89	fn into_value(self) -> Value {
90		Value::TinyUnsigned(Some(self))
91	}
92}
93
94impl IntoValue for Option<u8> {
95	fn into_value(self) -> Value {
96		Value::TinyUnsigned(self)
97	}
98}
99
100impl IntoValue for u16 {
101	fn into_value(self) -> Value {
102		Value::SmallUnsigned(Some(self))
103	}
104}
105
106impl IntoValue for Option<u16> {
107	fn into_value(self) -> Value {
108		Value::SmallUnsigned(self)
109	}
110}
111
112impl IntoValue for u32 {
113	fn into_value(self) -> Value {
114		Value::Unsigned(Some(self))
115	}
116}
117
118impl IntoValue for Option<u32> {
119	fn into_value(self) -> Value {
120		Value::Unsigned(self)
121	}
122}
123
124impl IntoValue for u64 {
125	fn into_value(self) -> Value {
126		Value::BigUnsigned(Some(self))
127	}
128}
129
130impl IntoValue for Option<u64> {
131	fn into_value(self) -> Value {
132		Value::BigUnsigned(self)
133	}
134}
135
136impl IntoValue for f32 {
137	fn into_value(self) -> Value {
138		Value::Float(Some(self))
139	}
140}
141
142impl IntoValue for Option<f32> {
143	fn into_value(self) -> Value {
144		Value::Float(self)
145	}
146}
147
148impl IntoValue for f64 {
149	fn into_value(self) -> Value {
150		Value::Double(Some(self))
151	}
152}
153
154impl IntoValue for Option<f64> {
155	fn into_value(self) -> Value {
156		Value::Double(self)
157	}
158}
159
160impl IntoValue for char {
161	fn into_value(self) -> Value {
162		Value::Char(Some(self))
163	}
164}
165
166impl IntoValue for Option<char> {
167	fn into_value(self) -> Value {
168		Value::Char(self)
169	}
170}
171
172// =============================================================================
173// Implementations for String types
174// =============================================================================
175
176impl IntoValue for String {
177	fn into_value(self) -> Value {
178		Value::String(Some(Box::new(self)))
179	}
180}
181
182impl IntoValue for Option<String> {
183	fn into_value(self) -> Value {
184		Value::String(self.map(Box::new))
185	}
186}
187
188impl IntoValue for &str {
189	fn into_value(self) -> Value {
190		Value::String(Some(Box::new(self.to_owned())))
191	}
192}
193
194impl IntoValue for Option<&str> {
195	fn into_value(self) -> Value {
196		Value::String(self.map(|s| Box::new(s.to_owned())))
197	}
198}
199
200impl IntoValue for &String {
201	fn into_value(self) -> Value {
202		Value::String(Some(Box::new(self.clone())))
203	}
204}
205
206impl IntoValue for Box<String> {
207	fn into_value(self) -> Value {
208		Value::String(Some(self))
209	}
210}
211
212impl IntoValue for Option<Box<String>> {
213	fn into_value(self) -> Value {
214		Value::String(self)
215	}
216}
217
218impl IntoValue for std::borrow::Cow<'_, str> {
219	fn into_value(self) -> Value {
220		Value::String(Some(Box::new(self.into_owned())))
221	}
222}
223
224// =============================================================================
225// Implementations for Bytes types
226// =============================================================================
227
228impl IntoValue for Vec<u8> {
229	fn into_value(self) -> Value {
230		Value::Bytes(Some(Box::new(self)))
231	}
232}
233
234impl IntoValue for Option<Vec<u8>> {
235	fn into_value(self) -> Value {
236		Value::Bytes(self.map(Box::new))
237	}
238}
239
240impl IntoValue for &[u8] {
241	fn into_value(self) -> Value {
242		Value::Bytes(Some(Box::new(self.to_vec())))
243	}
244}
245
246// =============================================================================
247// Implementation for Value itself (identity)
248// =============================================================================
249
250impl IntoValue for Value {
251	fn into_value(self) -> Value {
252		self
253	}
254}
255
256// =============================================================================
257// Into<Value> implementations (delegate to IntoValue)
258// =============================================================================
259
260impl From<bool> for Value {
261	fn from(v: bool) -> Self {
262		v.into_value()
263	}
264}
265
266impl From<i8> for Value {
267	fn from(v: i8) -> Self {
268		v.into_value()
269	}
270}
271
272impl From<i16> for Value {
273	fn from(v: i16) -> Self {
274		v.into_value()
275	}
276}
277
278impl From<i32> for Value {
279	fn from(v: i32) -> Self {
280		v.into_value()
281	}
282}
283
284impl From<i64> for Value {
285	fn from(v: i64) -> Self {
286		v.into_value()
287	}
288}
289
290impl From<u8> for Value {
291	fn from(v: u8) -> Self {
292		v.into_value()
293	}
294}
295
296impl From<u16> for Value {
297	fn from(v: u16) -> Self {
298		v.into_value()
299	}
300}
301
302impl From<u32> for Value {
303	fn from(v: u32) -> Self {
304		v.into_value()
305	}
306}
307
308impl From<u64> for Value {
309	fn from(v: u64) -> Self {
310		v.into_value()
311	}
312}
313
314impl From<f32> for Value {
315	fn from(v: f32) -> Self {
316		v.into_value()
317	}
318}
319
320impl From<f64> for Value {
321	fn from(v: f64) -> Self {
322		v.into_value()
323	}
324}
325
326impl From<char> for Value {
327	fn from(v: char) -> Self {
328		v.into_value()
329	}
330}
331
332impl From<String> for Value {
333	fn from(v: String) -> Self {
334		v.into_value()
335	}
336}
337
338impl From<&str> for Value {
339	fn from(v: &str) -> Self {
340		v.into_value()
341	}
342}
343
344impl From<Vec<u8>> for Value {
345	fn from(v: Vec<u8>) -> Self {
346		v.into_value()
347	}
348}
349
350impl From<&[u8]> for Value {
351	fn from(v: &[u8]) -> Self {
352		v.into_value()
353	}
354}
355
356// =============================================================================
357// Feature-gated implementations: chrono
358// =============================================================================
359
360#[cfg(feature = "with-chrono")]
361impl IntoValue for chrono::NaiveDate {
362	fn into_value(self) -> Value {
363		Value::ChronoDate(Some(Box::new(self)))
364	}
365}
366
367#[cfg(feature = "with-chrono")]
368impl IntoValue for Option<chrono::NaiveDate> {
369	fn into_value(self) -> Value {
370		Value::ChronoDate(self.map(Box::new))
371	}
372}
373
374#[cfg(feature = "with-chrono")]
375impl IntoValue for chrono::NaiveTime {
376	fn into_value(self) -> Value {
377		Value::ChronoTime(Some(Box::new(self)))
378	}
379}
380
381#[cfg(feature = "with-chrono")]
382impl IntoValue for Option<chrono::NaiveTime> {
383	fn into_value(self) -> Value {
384		Value::ChronoTime(self.map(Box::new))
385	}
386}
387
388#[cfg(feature = "with-chrono")]
389impl IntoValue for chrono::NaiveDateTime {
390	fn into_value(self) -> Value {
391		Value::ChronoDateTime(Some(Box::new(self)))
392	}
393}
394
395#[cfg(feature = "with-chrono")]
396impl IntoValue for Option<chrono::NaiveDateTime> {
397	fn into_value(self) -> Value {
398		Value::ChronoDateTime(self.map(Box::new))
399	}
400}
401
402#[cfg(feature = "with-chrono")]
403impl IntoValue for chrono::DateTime<chrono::Utc> {
404	fn into_value(self) -> Value {
405		Value::ChronoDateTimeUtc(Some(Box::new(self)))
406	}
407}
408
409#[cfg(feature = "with-chrono")]
410impl IntoValue for Option<chrono::DateTime<chrono::Utc>> {
411	fn into_value(self) -> Value {
412		Value::ChronoDateTimeUtc(self.map(Box::new))
413	}
414}
415
416#[cfg(feature = "with-chrono")]
417impl IntoValue for chrono::DateTime<chrono::Local> {
418	fn into_value(self) -> Value {
419		Value::ChronoDateTimeLocal(Some(Box::new(self)))
420	}
421}
422
423#[cfg(feature = "with-chrono")]
424impl IntoValue for Option<chrono::DateTime<chrono::Local>> {
425	fn into_value(self) -> Value {
426		Value::ChronoDateTimeLocal(self.map(Box::new))
427	}
428}
429
430#[cfg(feature = "with-chrono")]
431impl IntoValue for chrono::DateTime<chrono::FixedOffset> {
432	fn into_value(self) -> Value {
433		Value::ChronoDateTimeWithTimeZone(Some(Box::new(self)))
434	}
435}
436
437#[cfg(feature = "with-chrono")]
438impl IntoValue for Option<chrono::DateTime<chrono::FixedOffset>> {
439	fn into_value(self) -> Value {
440		Value::ChronoDateTimeWithTimeZone(self.map(Box::new))
441	}
442}
443
444#[cfg(feature = "with-chrono")]
445impl From<chrono::NaiveDate> for Value {
446	fn from(v: chrono::NaiveDate) -> Self {
447		v.into_value()
448	}
449}
450
451#[cfg(feature = "with-chrono")]
452impl From<chrono::NaiveTime> for Value {
453	fn from(v: chrono::NaiveTime) -> Self {
454		v.into_value()
455	}
456}
457
458#[cfg(feature = "with-chrono")]
459impl From<chrono::NaiveDateTime> for Value {
460	fn from(v: chrono::NaiveDateTime) -> Self {
461		v.into_value()
462	}
463}
464
465#[cfg(feature = "with-chrono")]
466impl From<chrono::DateTime<chrono::Utc>> for Value {
467	fn from(v: chrono::DateTime<chrono::Utc>) -> Self {
468		v.into_value()
469	}
470}
471
472#[cfg(feature = "with-chrono")]
473impl From<chrono::DateTime<chrono::Local>> for Value {
474	fn from(v: chrono::DateTime<chrono::Local>) -> Self {
475		v.into_value()
476	}
477}
478
479#[cfg(feature = "with-chrono")]
480impl From<chrono::DateTime<chrono::FixedOffset>> for Value {
481	fn from(v: chrono::DateTime<chrono::FixedOffset>) -> Self {
482		v.into_value()
483	}
484}
485
486// =============================================================================
487// Feature-gated implementations: uuid
488// =============================================================================
489
490#[cfg(feature = "with-uuid")]
491impl IntoValue for uuid::Uuid {
492	fn into_value(self) -> Value {
493		Value::Uuid(Some(Box::new(self)))
494	}
495}
496
497#[cfg(feature = "with-uuid")]
498impl IntoValue for Option<uuid::Uuid> {
499	fn into_value(self) -> Value {
500		Value::Uuid(self.map(Box::new))
501	}
502}
503
504#[cfg(feature = "with-uuid")]
505impl From<uuid::Uuid> for Value {
506	fn from(v: uuid::Uuid) -> Self {
507		v.into_value()
508	}
509}
510
511// =============================================================================
512// Feature-gated implementations: json
513// =============================================================================
514
515#[cfg(feature = "with-json")]
516impl IntoValue for serde_json::Value {
517	fn into_value(self) -> Value {
518		Value::Json(Some(Box::new(self)))
519	}
520}
521
522#[cfg(feature = "with-json")]
523impl IntoValue for Option<serde_json::Value> {
524	fn into_value(self) -> Value {
525		Value::Json(self.map(Box::new))
526	}
527}
528
529#[cfg(feature = "with-json")]
530impl From<serde_json::Value> for Value {
531	fn from(v: serde_json::Value) -> Self {
532		v.into_value()
533	}
534}
535
536// =============================================================================
537// Feature-gated implementations: rust_decimal
538// =============================================================================
539
540#[cfg(feature = "with-rust_decimal")]
541impl IntoValue for rust_decimal::Decimal {
542	fn into_value(self) -> Value {
543		Value::Decimal(Some(Box::new(self)))
544	}
545}
546
547#[cfg(feature = "with-rust_decimal")]
548impl IntoValue for Option<rust_decimal::Decimal> {
549	fn into_value(self) -> Value {
550		Value::Decimal(self.map(Box::new))
551	}
552}
553
554#[cfg(feature = "with-rust_decimal")]
555impl From<rust_decimal::Decimal> for Value {
556	fn from(v: rust_decimal::Decimal) -> Self {
557		v.into_value()
558	}
559}
560
561// =============================================================================
562// Feature-gated implementations: bigdecimal
563// =============================================================================
564
565#[cfg(feature = "with-bigdecimal")]
566impl IntoValue for bigdecimal::BigDecimal {
567	fn into_value(self) -> Value {
568		Value::BigDecimal(Some(Box::new(self)))
569	}
570}
571
572#[cfg(feature = "with-bigdecimal")]
573impl IntoValue for Option<bigdecimal::BigDecimal> {
574	fn into_value(self) -> Value {
575		Value::BigDecimal(self.map(Box::new))
576	}
577}
578
579#[cfg(feature = "with-bigdecimal")]
580impl From<bigdecimal::BigDecimal> for Value {
581	fn from(v: bigdecimal::BigDecimal) -> Self {
582		v.into_value()
583	}
584}