1use super::MySQLValue;
4use crate::prelude::*;
5
6macro_rules! integer_values {
7 ($($variant:ident: [$($ty:ty),+ $(,)?]),+ $(,)?) => {
8 $(
9 $(
10 impl From<$ty> for MySQLValue<'_> {
11 fn from(value: $ty) -> Self {
12 Self::$variant(value as _)
13 }
14 }
15
16 impl From<&$ty> for MySQLValue<'_> {
17 fn from(value: &$ty) -> Self {
18 Self::from(*value)
19 }
20 }
21 )+
22 )+
23 };
24}
25
26integer_values!(
27 Int: [i8, i16, i32, i64, isize],
28 UInt: [u8, u16, u32, u64, usize],
29);
30
31impl From<bool> for MySQLValue<'_> {
32 fn from(value: bool) -> Self {
33 Self::Int(i64::from(value))
34 }
35}
36
37impl From<&bool> for MySQLValue<'_> {
38 fn from(value: &bool) -> Self {
39 Self::from(*value)
40 }
41}
42
43impl From<char> for MySQLValue<'_> {
44 fn from(value: char) -> Self {
45 Self::from(String::from(value))
46 }
47}
48
49impl From<f32> for MySQLValue<'_> {
50 fn from(value: f32) -> Self {
51 Self::Float(value)
52 }
53}
54
55impl From<&f32> for MySQLValue<'_> {
56 fn from(value: &f32) -> Self {
57 Self::Float(*value)
58 }
59}
60
61impl From<f64> for MySQLValue<'_> {
62 fn from(value: f64) -> Self {
63 Self::Double(value)
64 }
65}
66
67impl From<&f64> for MySQLValue<'_> {
68 fn from(value: &f64) -> Self {
69 Self::Double(*value)
70 }
71}
72
73impl<'a> From<&'a str> for MySQLValue<'a> {
74 fn from(value: &'a str) -> Self {
75 Self::Bytes(Cow::Borrowed(value.as_bytes()))
76 }
77}
78
79impl<'a> From<Cow<'a, str>> for MySQLValue<'a> {
80 fn from(value: Cow<'a, str>) -> Self {
81 match value {
82 Cow::Borrowed(value) => Self::Bytes(Cow::Borrowed(value.as_bytes())),
83 Cow::Owned(value) => Self::Bytes(Cow::Owned(value.into_bytes())),
84 }
85 }
86}
87
88impl From<String> for MySQLValue<'_> {
89 fn from(value: String) -> Self {
90 Self::Bytes(Cow::Owned(value.into_bytes()))
91 }
92}
93
94impl<'a> From<&'a String> for MySQLValue<'a> {
95 fn from(value: &'a String) -> Self {
96 Self::from(value.as_str())
97 }
98}
99
100macro_rules! owned_string_wrapper {
101 ($wrapper:ident) => {
102 impl From<$wrapper<String>> for MySQLValue<'_> {
103 fn from(value: $wrapper<String>) -> Self {
104 Self::Bytes(Cow::Owned(value.as_bytes().to_vec()))
105 }
106 }
107
108 impl<'a> From<&'a $wrapper<String>> for MySQLValue<'a> {
109 fn from(value: &'a $wrapper<String>) -> Self {
110 Self::Bytes(Cow::Borrowed(value.as_bytes()))
111 }
112 }
113
114 impl From<$wrapper<str>> for MySQLValue<'_> {
115 fn from(value: $wrapper<str>) -> Self {
116 Self::Bytes(Cow::Owned(value.as_bytes().to_vec()))
117 }
118 }
119
120 impl<'a> From<&'a $wrapper<str>> for MySQLValue<'a> {
121 fn from(value: &'a $wrapper<str>) -> Self {
122 Self::Bytes(Cow::Borrowed(value.as_bytes()))
123 }
124 }
125 };
126}
127
128owned_string_wrapper!(Box);
129owned_string_wrapper!(Rc);
130owned_string_wrapper!(Arc);
131
132#[cfg(feature = "compact-str")]
133impl From<compact_str::CompactString> for MySQLValue<'_> {
134 fn from(value: compact_str::CompactString) -> Self {
135 Self::Bytes(Cow::Owned(value.as_bytes().to_vec()))
136 }
137}
138
139#[cfg(feature = "compact-str")]
140impl<'a> From<&'a compact_str::CompactString> for MySQLValue<'a> {
141 fn from(value: &'a compact_str::CompactString) -> Self {
142 Self::Bytes(Cow::Borrowed(value.as_bytes()))
143 }
144}
145
146#[cfg(feature = "arrayvec")]
147impl<const N: usize> From<arrayvec::ArrayString<N>> for MySQLValue<'_> {
148 fn from(value: arrayvec::ArrayString<N>) -> Self {
149 Self::Bytes(Cow::Owned(value.as_bytes().to_vec()))
150 }
151}
152
153#[cfg(feature = "arrayvec")]
154impl<'a, const N: usize> From<&'a arrayvec::ArrayString<N>> for MySQLValue<'a> {
155 fn from(value: &'a arrayvec::ArrayString<N>) -> Self {
156 Self::Bytes(Cow::Borrowed(value.as_bytes()))
157 }
158}
159
160impl<'a> From<&'a [u8]> for MySQLValue<'a> {
161 fn from(value: &'a [u8]) -> Self {
162 Self::Bytes(Cow::Borrowed(value))
163 }
164}
165
166impl<'a> From<Cow<'a, [u8]>> for MySQLValue<'a> {
167 fn from(value: Cow<'a, [u8]>) -> Self {
168 Self::Bytes(value)
169 }
170}
171
172impl From<Vec<u8>> for MySQLValue<'_> {
173 fn from(value: Vec<u8>) -> Self {
174 Self::Bytes(Cow::Owned(value))
175 }
176}
177
178impl<const N: usize> From<[u8; N]> for MySQLValue<'_> {
179 fn from(value: [u8; N]) -> Self {
180 Self::Bytes(Cow::Owned(value.to_vec()))
181 }
182}
183
184impl<'a, const N: usize> From<&'a [u8; N]> for MySQLValue<'a> {
185 fn from(value: &'a [u8; N]) -> Self {
186 Self::Bytes(Cow::Borrowed(value))
187 }
188}
189
190impl<const N: usize> From<[char; N]> for MySQLValue<'_> {
191 fn from(value: [char; N]) -> Self {
192 Self::from(value.into_iter().collect::<String>())
193 }
194}
195
196impl<const N: usize> From<&[char; N]> for MySQLValue<'_> {
197 fn from(value: &[char; N]) -> Self {
198 Self::from(value.iter().collect::<String>())
199 }
200}
201
202macro_rules! owned_bytes_wrapper {
203 ($wrapper:ident) => {
204 impl From<$wrapper<Vec<u8>>> for MySQLValue<'_> {
205 fn from(value: $wrapper<Vec<u8>>) -> Self {
206 Self::Bytes(Cow::Owned(value.as_slice().to_vec()))
207 }
208 }
209
210 impl<'a> From<&'a $wrapper<Vec<u8>>> for MySQLValue<'a> {
211 fn from(value: &'a $wrapper<Vec<u8>>) -> Self {
212 Self::Bytes(Cow::Borrowed(value.as_slice()))
213 }
214 }
215 };
216}
217
218owned_bytes_wrapper!(Box);
219owned_bytes_wrapper!(Rc);
220owned_bytes_wrapper!(Arc);
221
222#[cfg(feature = "arrayvec")]
223impl<const N: usize> From<arrayvec::ArrayVec<u8, N>> for MySQLValue<'_> {
224 fn from(value: arrayvec::ArrayVec<u8, N>) -> Self {
225 Self::Bytes(Cow::Owned(value.into_iter().collect()))
226 }
227}
228
229#[cfg(feature = "arrayvec")]
230impl<'a, const N: usize> From<&'a arrayvec::ArrayVec<u8, N>> for MySQLValue<'a> {
231 fn from(value: &'a arrayvec::ArrayVec<u8, N>) -> Self {
232 Self::Bytes(Cow::Borrowed(value.as_slice()))
233 }
234}
235
236#[cfg(feature = "smallvec")]
237impl<const N: usize> From<smallvec::SmallVec<[u8; N]>> for MySQLValue<'_> {
238 fn from(value: smallvec::SmallVec<[u8; N]>) -> Self {
239 Self::Bytes(Cow::Owned(value.into_vec()))
240 }
241}
242
243#[cfg(feature = "smallvec")]
244impl<'a, const N: usize> From<&'a smallvec::SmallVec<[u8; N]>> for MySQLValue<'a> {
245 fn from(value: &'a smallvec::SmallVec<[u8; N]>) -> Self {
246 Self::Bytes(Cow::Borrowed(value.as_slice()))
247 }
248}
249
250#[cfg(feature = "bytes")]
251impl From<bytes::Bytes> for MySQLValue<'_> {
252 fn from(value: bytes::Bytes) -> Self {
253 Self::Bytes(Cow::Owned(value.to_vec()))
254 }
255}
256
257#[cfg(feature = "bytes")]
258impl From<bytes::BytesMut> for MySQLValue<'_> {
259 fn from(value: bytes::BytesMut) -> Self {
260 Self::Bytes(Cow::Owned(value.to_vec()))
261 }
262}
263
264#[cfg(feature = "bytes")]
265impl From<&bytes::Bytes> for MySQLValue<'_> {
266 fn from(value: &bytes::Bytes) -> Self {
267 Self::Bytes(Cow::Owned(value.to_vec()))
268 }
269}
270
271#[cfg(feature = "bytes")]
272impl From<&bytes::BytesMut> for MySQLValue<'_> {
273 fn from(value: &bytes::BytesMut) -> Self {
274 Self::Bytes(Cow::Owned(value.to_vec()))
275 }
276}
277
278#[cfg(feature = "uuid")]
279impl From<uuid::Uuid> for MySQLValue<'_> {
280 fn from(value: uuid::Uuid) -> Self {
281 Self::Bytes(Cow::Owned(value.into_bytes().to_vec()))
282 }
283}
284
285#[cfg(feature = "uuid")]
286impl<'a> From<&'a uuid::Uuid> for MySQLValue<'a> {
287 fn from(value: &'a uuid::Uuid) -> Self {
288 Self::Bytes(Cow::Borrowed(value.as_bytes()))
289 }
290}
291
292#[cfg(feature = "serde")]
293impl From<serde_json::Value> for MySQLValue<'_> {
294 fn from(value: serde_json::Value) -> Self {
295 Self::Bytes(Cow::Owned(value.to_string().into_bytes()))
296 }
297}
298
299#[cfg(feature = "serde")]
300impl From<&serde_json::Value> for MySQLValue<'_> {
301 fn from(value: &serde_json::Value) -> Self {
302 Self::Bytes(Cow::Owned(value.to_string().into_bytes()))
303 }
304}
305
306#[cfg(feature = "rust-decimal")]
307impl From<rust_decimal::Decimal> for MySQLValue<'_> {
308 fn from(value: rust_decimal::Decimal) -> Self {
309 Self::Bytes(Cow::Owned(value.to_string().into_bytes()))
310 }
311}
312
313#[cfg(feature = "rust-decimal")]
314impl From<&rust_decimal::Decimal> for MySQLValue<'_> {
315 fn from(value: &rust_decimal::Decimal) -> Self {
316 Self::Bytes(Cow::Owned(value.to_string().into_bytes()))
317 }
318}
319
320#[cfg(any(feature = "chrono", feature = "time", feature = "jiff"))]
321struct DateParts {
322 year: i32,
323 month: u8,
324 day: u8,
325 hour: u8,
326 minute: u8,
327 second: u8,
328 microseconds: u32,
329}
330
331#[cfg(any(feature = "chrono", feature = "time", feature = "jiff"))]
332fn date_value(parts: DateParts, fallback: String) -> MySQLValue<'static> {
333 match u16::try_from(parts.year) {
334 Ok(year) if (1000..=9999).contains(&year) => MySQLValue::Date {
335 year,
336 month: parts.month,
337 day: parts.day,
338 hour: parts.hour,
339 minute: parts.minute,
340 second: parts.second,
341 microseconds: parts.microseconds,
342 },
343 _ => MySQLValue::Bytes(Cow::Owned(fallback.into_bytes())),
344 }
345}
346
347#[cfg(feature = "chrono")]
348fn chrono_date(value: chrono::NaiveDate) -> MySQLValue<'static> {
349 use chrono::Datelike;
350
351 date_value(
352 DateParts {
353 year: value.year(),
354 month: value.month() as u8,
355 day: value.day() as u8,
356 hour: 0,
357 minute: 0,
358 second: 0,
359 microseconds: 0,
360 },
361 value.to_string(),
362 )
363}
364
365#[cfg(feature = "chrono")]
366fn chrono_datetime(value: chrono::NaiveDateTime) -> MySQLValue<'static> {
367 use chrono::{Datelike, Timelike};
368
369 date_value(
370 DateParts {
371 year: value.year(),
372 month: value.month() as u8,
373 day: value.day() as u8,
374 hour: value.hour() as u8,
375 minute: value.minute() as u8,
376 second: value.second() as u8,
377 microseconds: value.nanosecond() / 1_000,
378 },
379 value.to_string(),
380 )
381}
382
383#[cfg(feature = "chrono")]
384impl From<chrono::NaiveDate> for MySQLValue<'_> {
385 fn from(value: chrono::NaiveDate) -> Self {
386 chrono_date(value)
387 }
388}
389
390#[cfg(feature = "chrono")]
391impl From<&chrono::NaiveDate> for MySQLValue<'_> {
392 fn from(value: &chrono::NaiveDate) -> Self {
393 chrono_date(*value)
394 }
395}
396
397#[cfg(feature = "chrono")]
398impl From<chrono::NaiveTime> for MySQLValue<'_> {
399 fn from(value: chrono::NaiveTime) -> Self {
400 use chrono::Timelike;
401
402 Self::Time {
403 negative: false,
404 days: 0,
405 hours: value.hour() as u8,
406 minutes: value.minute() as u8,
407 seconds: value.second() as u8,
408 microseconds: value.nanosecond() / 1_000,
409 }
410 }
411}
412
413#[cfg(feature = "chrono")]
414impl From<&chrono::NaiveTime> for MySQLValue<'_> {
415 fn from(value: &chrono::NaiveTime) -> Self {
416 Self::from(*value)
417 }
418}
419
420#[cfg(feature = "chrono")]
421impl From<chrono::NaiveDateTime> for MySQLValue<'_> {
422 fn from(value: chrono::NaiveDateTime) -> Self {
423 chrono_datetime(value)
424 }
425}
426
427#[cfg(feature = "chrono")]
428impl From<&chrono::NaiveDateTime> for MySQLValue<'_> {
429 fn from(value: &chrono::NaiveDateTime) -> Self {
430 chrono_datetime(*value)
431 }
432}
433
434#[cfg(feature = "chrono")]
435impl From<chrono::DateTime<chrono::Utc>> for MySQLValue<'_> {
436 fn from(value: chrono::DateTime<chrono::Utc>) -> Self {
437 chrono_datetime(value.naive_utc())
438 }
439}
440
441#[cfg(feature = "chrono")]
442impl From<chrono::DateTime<chrono::FixedOffset>> for MySQLValue<'_> {
443 fn from(value: chrono::DateTime<chrono::FixedOffset>) -> Self {
444 chrono_datetime(value.with_timezone(&chrono::Utc).naive_utc())
445 }
446}
447
448#[cfg(feature = "time")]
449fn time_date(value: time::Date) -> MySQLValue<'static> {
450 date_value(
451 DateParts {
452 year: value.year(),
453 month: u8::from(value.month()),
454 day: value.day(),
455 hour: 0,
456 minute: 0,
457 second: 0,
458 microseconds: 0,
459 },
460 value.to_string(),
461 )
462}
463
464#[cfg(feature = "time")]
465fn time_datetime(value: time::PrimitiveDateTime) -> MySQLValue<'static> {
466 date_value(
467 DateParts {
468 year: value.year(),
469 month: u8::from(value.month()),
470 day: value.day(),
471 hour: value.hour(),
472 minute: value.minute(),
473 second: value.second(),
474 microseconds: value.microsecond(),
475 },
476 value.to_string(),
477 )
478}
479
480#[cfg(feature = "time")]
481impl From<time::Date> for MySQLValue<'_> {
482 fn from(value: time::Date) -> Self {
483 time_date(value)
484 }
485}
486
487#[cfg(feature = "time")]
488impl From<&time::Date> for MySQLValue<'_> {
489 fn from(value: &time::Date) -> Self {
490 time_date(*value)
491 }
492}
493
494#[cfg(feature = "time")]
495impl From<time::Time> for MySQLValue<'_> {
496 fn from(value: time::Time) -> Self {
497 Self::Time {
498 negative: false,
499 days: 0,
500 hours: value.hour(),
501 minutes: value.minute(),
502 seconds: value.second(),
503 microseconds: value.microsecond(),
504 }
505 }
506}
507
508#[cfg(feature = "time")]
509impl From<&time::Time> for MySQLValue<'_> {
510 fn from(value: &time::Time) -> Self {
511 Self::from(*value)
512 }
513}
514
515#[cfg(feature = "time")]
516impl From<time::PrimitiveDateTime> for MySQLValue<'_> {
517 fn from(value: time::PrimitiveDateTime) -> Self {
518 time_datetime(value)
519 }
520}
521
522#[cfg(feature = "time")]
523impl From<&time::PrimitiveDateTime> for MySQLValue<'_> {
524 fn from(value: &time::PrimitiveDateTime) -> Self {
525 time_datetime(*value)
526 }
527}
528
529#[cfg(feature = "time")]
530impl From<time::OffsetDateTime> for MySQLValue<'_> {
531 fn from(value: time::OffsetDateTime) -> Self {
532 let utc = value.to_offset(time::UtcOffset::UTC);
533 time_datetime(time::PrimitiveDateTime::new(utc.date(), utc.time()))
534 }
535}
536
537#[cfg(feature = "jiff")]
538fn jiff_date(value: jiff::civil::Date) -> MySQLValue<'static> {
539 date_value(
540 DateParts {
541 year: i32::from(value.year()),
542 month: value.month().unsigned_abs(),
543 day: value.day().unsigned_abs(),
544 hour: 0,
545 minute: 0,
546 second: 0,
547 microseconds: 0,
548 },
549 value.to_string(),
550 )
551}
552
553#[cfg(feature = "jiff")]
554fn jiff_datetime(value: jiff::civil::DateTime) -> MySQLValue<'static> {
555 date_value(
556 DateParts {
557 year: i32::from(value.year()),
558 month: value.month().unsigned_abs(),
559 day: value.day().unsigned_abs(),
560 hour: value.hour().unsigned_abs(),
561 minute: value.minute().unsigned_abs(),
562 second: value.second().unsigned_abs(),
563 microseconds: value.subsec_nanosecond().unsigned_abs() / 1_000,
564 },
565 value.to_string(),
566 )
567}
568
569#[cfg(feature = "jiff")]
570impl From<jiff::civil::Date> for MySQLValue<'_> {
571 fn from(value: jiff::civil::Date) -> Self {
572 jiff_date(value)
573 }
574}
575
576#[cfg(feature = "jiff")]
577impl From<&jiff::civil::Date> for MySQLValue<'_> {
578 fn from(value: &jiff::civil::Date) -> Self {
579 jiff_date(*value)
580 }
581}
582
583#[cfg(feature = "jiff")]
584impl From<jiff::civil::Time> for MySQLValue<'_> {
585 fn from(value: jiff::civil::Time) -> Self {
586 Self::Time {
587 negative: false,
588 days: 0,
589 hours: value.hour().unsigned_abs(),
590 minutes: value.minute().unsigned_abs(),
591 seconds: value.second().unsigned_abs(),
592 microseconds: value.subsec_nanosecond().unsigned_abs() / 1_000,
593 }
594 }
595}
596
597#[cfg(feature = "jiff")]
598impl From<&jiff::civil::Time> for MySQLValue<'_> {
599 fn from(value: &jiff::civil::Time) -> Self {
600 Self::from(*value)
601 }
602}
603
604#[cfg(feature = "jiff")]
605impl From<jiff::civil::DateTime> for MySQLValue<'_> {
606 fn from(value: jiff::civil::DateTime) -> Self {
607 jiff_datetime(value)
608 }
609}
610
611#[cfg(feature = "jiff")]
612impl From<&jiff::civil::DateTime> for MySQLValue<'_> {
613 fn from(value: &jiff::civil::DateTime) -> Self {
614 jiff_datetime(*value)
615 }
616}
617
618#[cfg(feature = "jiff")]
621impl From<jiff::Timestamp> for MySQLValue<'_> {
622 fn from(value: jiff::Timestamp) -> Self {
623 jiff_datetime(jiff::tz::Offset::UTC.to_datetime(value))
624 }
625}
626
627#[cfg(feature = "jiff")]
628impl From<&jiff::Timestamp> for MySQLValue<'_> {
629 fn from(value: &jiff::Timestamp) -> Self {
630 Self::from(*value)
631 }
632}
633
634impl<'a, T> From<Option<T>> for MySQLValue<'a>
635where
636 MySQLValue<'a>: From<T>,
637{
638 fn from(value: Option<T>) -> Self {
639 value.map_or(Self::Null, MySQLValue::from)
640 }
641}
642
643impl<'a> From<MySQLValue<'a>> for Cow<'a, MySQLValue<'a>> {
644 fn from(value: MySQLValue<'a>) -> Self {
645 Cow::Owned(value)
646 }
647}
648
649impl<'a> From<&'a MySQLValue<'a>> for Cow<'a, MySQLValue<'a>> {
650 fn from(value: &'a MySQLValue<'a>) -> Self {
651 Cow::Borrowed(value)
652 }
653}