1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
use serde; use std::{i16, i32, i8, u16, u32, u8}; use std::marker::Sized; use crate::de::{ConversionError, DeserializationError}; use crate::de::field_deserializer::FieldDeserializer; /// Defines into which rust types we support deserialization of fields. pub trait DbValue : Sized + DbValueInto<bool> + DbValueInto<u8> + DbValueInto<u16> + DbValueInto<u32> + DbValueInto<u64> + DbValueInto<i8> + DbValueInto<i16> + DbValueInto<i32> + DbValueInto<i64> + DbValueInto<f32> + DbValueInto<f64> + DbValueInto<String> + DbValueInto<Vec<u8>> { /// Returns true if this is a NULL value. fn is_null(&self) -> bool; /// Converts the DbValue into a plain rust value. fn into_typed<'de, T>(self) -> Result<T, DeserializationError> where T: serde::de::Deserialize<'de>, { Ok(serde::de::Deserialize::deserialize(FieldDeserializer::new(self))?) } } /// Conversion into a specific type. /// /// We recommend to implement this function in an as-graceful-as-possible mode, i.e., /// supporting every call as long as the concrete value can be converted. For the numeric /// types this requires quite some lines of code, but the effort pays off: it makes the usage of /// `serde_db` much more user-friendly. /// /// Example: /// /// ```ignore /// impl DbValueInto<u32> for MyDbValue { /// fn try_into(self) -> Result<u32, ConversionError> { /// match self { /// MyDbValue::TINYINT(u) | /// MyDbValue::NULLABLE_TINYINT(Some(u)) => Ok(u as u32), /// /// MyDbValue::SMALLINT(i) | /// MyDbValue::NULLABLE_SMALLINT(Some(i)) => { /// if i >= 0 { /// Ok(i as u32) /// } else { /// Err(ConversionError::NumberRange(...)) /// } /// } /// /// MyDbValue::INT(i) | /// MyDbValue::NULLABLE_INT(Some(i)) => { /// if i >= 0 { /// Ok(i as u32) /// } else { /// Err(ConversionError::NumberRange(...)) /// } /// } /// /// MyDbValue::BIGINT(i) | /// MyDbValue::NULLABLE_BIGINT(Some(i)) => { /// if (i >= 0) && (i <= u32::MAX as i64) { /// Ok(i as u32) /// } else { /// Err(ConversionError::NumberRange(...)) /// } /// } /// /// _ => Err(ConversionError::ValueType(...)), /// } /// } /// } /// ``` pub trait DbValueInto<T> { /// Tries to convert into type T. fn try_into(self) -> Result<T, ConversionError>; }