Add ToSql/FromSql for [u8; N]

This commit is contained in:
trevyn 2022-01-02 11:57:06 +03:00 committed by Thom Chiovoloni
parent 314977de4d
commit 7f09d295ba
5 changed files with 42 additions and 0 deletions

View File

@ -144,6 +144,9 @@ impl Context<'_> {
FromSqlError::Other(err) => {
Error::FromSqlConversionFailure(idx, value.data_type(), err)
}
FromSqlError::InvalidSize(_, _) => {
Error::FromSqlConversionFailure(idx, value.data_type(), Box::new(err))
}
#[cfg(feature = "i128_blob")]
FromSqlError::InvalidI128Size(_) => {
Error::FromSqlConversionFailure(idx, value.data_type(), Box::new(err))

View File

@ -290,6 +290,9 @@ impl<'stmt> Row<'stmt> {
FromSqlError::Other(err) => {
Error::FromSqlConversionFailure(idx as usize, value.data_type(), err)
}
FromSqlError::InvalidSize(_, _) => {
Error::FromSqlConversionFailure(idx as usize, value.data_type(), Box::new(err))
}
#[cfg(feature = "i128_blob")]
FromSqlError::InvalidI128Size(_) => Error::InvalidColumnType(
idx,

View File

@ -15,6 +15,10 @@ pub enum FromSqlError {
/// requested type.
OutOfRange(i64),
/// Error when the blob result returned by SQLite cannot be stored into the
/// requested type due to a size mismatch. (type size, blob size)
InvalidSize(usize, usize),
/// Error returned when reading an `i128` from a
/// blob with a size other than 16. Only available when the `i128_blob`
/// feature is enabled.
@ -51,6 +55,9 @@ impl fmt::Display for FromSqlError {
match *self {
FromSqlError::InvalidType => write!(f, "Invalid type"),
FromSqlError::OutOfRange(i) => write!(f, "Value {} out of range", i),
FromSqlError::InvalidSize(i, j) => {
write!(f, "Cannot read {} byte value out of {} byte blob", i, j)
}
#[cfg(feature = "i128_blob")]
FromSqlError::InvalidI128Size(s) => {
write!(f, "Cannot read 128bit value out of {} byte blob", s)
@ -177,6 +184,16 @@ impl FromSql for Vec<u8> {
}
}
impl<const N: usize> FromSql for [u8; N] {
#[inline]
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
let slice = value.as_blob()?;
slice
.try_into()
.map_err(|_| FromSqlError::InvalidSize(N, slice.len()))
}
}
#[cfg(feature = "i128_blob")]
#[cfg_attr(docsrs, doc(cfg(feature = "i128_blob")))]
impl FromSql for i128 {

View File

@ -224,6 +224,13 @@ impl ToSql for Vec<u8> {
}
}
impl<const N: usize> ToSql for [u8; N] {
#[inline]
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
Ok(ToSqlOutput::from(&self[..]))
}
}
impl ToSql for [u8] {
#[inline]
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
@ -265,6 +272,15 @@ mod test {
is_to_sql::<u32>();
}
#[test]
fn test_u8_array() {
let a: [u8; 99] = [0u8; 99];
let _a: &[&dyn ToSql] = crate::params![a];
let r = ToSql::to_sql(&a);
assert!(r.is_ok());
}
#[test]
fn test_cow_str() {
use std::borrow::Cow;

View File

@ -600,6 +600,9 @@ impl Values<'_> {
FromSqlError::Other(err) => {
Error::FromSqlConversionFailure(idx, value.data_type(), err)
}
FromSqlError::InvalidSize(_, _) => {
Error::FromSqlConversionFailure(idx, value.data_type(), Box::new(err))
}
FromSqlError::OutOfRange(i) => Error::IntegralValueOutOfRange(idx, i),
#[cfg(feature = "i128_blob")]
#[cfg_attr(docsrs, doc(cfg(feature = "i128_blob")))]