use crate::{sql_read_bytes::SqlReadBytes, time::DateTimeOffset, ColumnData};
pub(crate) async fn decode<R>(src: &mut R, len: usize) -> crate::Result<ColumnData<'static>>
where
R: SqlReadBytes + Unpin,
{
let rlen = src.read_u8().await?;
let dto = match rlen {
0 => ColumnData::DateTimeOffset(None),
_ => {
let time_len = rlen.checked_sub(5).ok_or_else(|| {
crate::Error::Protocol(
format!("datetimeoffset: invalid value length {rlen}").into(),
)
})?;
let dto = DateTimeOffset::decode(src, len, time_len).await?;
ColumnData::DateTimeOffset(Some(dto))
}
};
Ok(dto)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql_read_bytes::test_utils::IntoSqlReadBytes;
use bytes::BytesMut;
#[tokio::test]
async fn rejects_underlength_value_instead_of_panicking() {
let mut buf = BytesMut::new();
buf.extend_from_slice(&[4u8]);
let err = decode(&mut buf.into_sql_read_bytes(), 8)
.await
.expect_err("rlen < 5 must be rejected");
assert!(matches!(err, crate::Error::Protocol(_)));
}
}