diesel/mysql/
value.rs
1use super::types::date_and_time::MysqlTime;
2use super::MysqlType;
3use crate::deserialize;
4use std::error::Error;
5
6#[derive(Clone, Debug)]
8pub struct MysqlValue<'a> {
9 raw: &'a [u8],
10 tpe: MysqlType,
11}
12
13impl<'a> MysqlValue<'a> {
14 #[cfg(feature = "i-implement-a-third-party-backend-and-opt-into-breaking-changes")]
18 pub fn new(raw: &'a [u8], tpe: MysqlType) -> Self {
19 Self::new_internal(raw, tpe)
20 }
21
22 pub(in crate::mysql) fn new_internal(raw: &'a [u8], tpe: MysqlType) -> Self {
23 Self { raw, tpe }
24 }
25
26 pub fn as_bytes(&self) -> &[u8] {
28 self.raw
29 }
30
31 pub fn value_type(&self) -> MysqlType {
33 self.tpe
34 }
35
36 #[allow(dead_code, clippy::cast_ptr_alignment)]
42 #[allow(unsafe_code)] pub(crate) fn time_value(&self) -> deserialize::Result<MysqlTime> {
44 match self.tpe {
45 MysqlType::Time | MysqlType::Date | MysqlType::DateTime | MysqlType::Timestamp => {
46 let ptr = self.raw.as_ptr() as *const MysqlTime;
47 let result = unsafe { ptr.read_unaligned() };
48 if result.neg {
49 Err("Negative dates/times are not yet supported".into())
50 } else {
51 Ok(result)
52 }
53 }
54 _ => Err(self.invalid_type_code("timestamp")),
55 }
56 }
57
58 pub(crate) fn numeric_value(&self) -> deserialize::Result<NumericRepresentation<'_>> {
61 Ok(match self.tpe {
62 MysqlType::UnsignedTiny | MysqlType::Tiny => {
63 NumericRepresentation::Tiny(self.raw[0].try_into()?)
64 }
65 MysqlType::UnsignedShort | MysqlType::Short => {
66 NumericRepresentation::Small(i16::from_ne_bytes((&self.raw[..2]).try_into()?))
67 }
68 MysqlType::UnsignedLong | MysqlType::Long => {
69 NumericRepresentation::Medium(i32::from_ne_bytes((&self.raw[..4]).try_into()?))
70 }
71 MysqlType::UnsignedLongLong | MysqlType::LongLong => {
72 NumericRepresentation::Big(i64::from_ne_bytes(self.raw.try_into()?))
73 }
74 MysqlType::Float => {
75 NumericRepresentation::Float(f32::from_ne_bytes(self.raw.try_into()?))
76 }
77 MysqlType::Double => {
78 NumericRepresentation::Double(f64::from_ne_bytes(self.raw.try_into()?))
79 }
80
81 MysqlType::Numeric => NumericRepresentation::Decimal(self.raw),
82 _ => return Err(self.invalid_type_code("number")),
83 })
84 }
85
86 fn invalid_type_code(&self, expected: &str) -> Box<dyn Error + Send + Sync> {
87 format!(
88 "Invalid representation received for {}: {:?}",
89 expected, self.tpe
90 )
91 .into()
92 }
93}
94
95#[derive(Debug, Clone, Copy)]
97#[non_exhaustive]
98pub enum NumericRepresentation<'a> {
99 Tiny(i8),
101 Small(i16),
103 Medium(i32),
105 Big(i64),
107 Float(f32),
109 Double(f64),
111 Decimal(&'a [u8]),
113}