use sqlx_core::{
database::Database,
encode::{Encode, IsNull},
error::BoxDynError,
types::Type,
};
use crate::{arguments::ExaBuffer, Exasol};
#[derive(Debug)]
pub struct ExaIter<I, T>
where
I: IntoIterator<Item = T> + Clone,
for<'q> T: Encode<'q, Exasol> + Type<Exasol>,
{
value: I,
}
impl<I, T> From<I> for ExaIter<I, T>
where
I: IntoIterator<Item = T> + Clone,
for<'q> T: Encode<'q, Exasol> + Type<Exasol>,
{
fn from(value: I) -> Self {
Self { value }
}
}
impl<T, I> Type<Exasol> for ExaIter<I, T>
where
I: IntoIterator<Item = T> + Clone,
for<'q> T: Encode<'q, Exasol> + Type<Exasol>,
{
fn type_info() -> <Exasol as Database>::TypeInfo {
T::type_info()
}
fn compatible(ty: &<Exasol as Database>::TypeInfo) -> bool {
<Self as Type<Exasol>>::type_info().compatible(ty)
}
}
impl<T, I> Encode<'_, Exasol> for ExaIter<I, T>
where
I: IntoIterator<Item = T> + Clone,
for<'q> T: Encode<'q, Exasol> + Type<Exasol>,
{
fn produces(&self) -> Option<<Exasol as Database>::TypeInfo> {
self.value
.clone()
.into_iter()
.next()
.as_ref()
.and_then(Encode::produces)
.or_else(|| Some(T::type_info()))
}
fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
buf.append_iter(self.value.clone())?;
Ok(IsNull::No)
}
fn size_hint(&self) -> usize {
self.value
.clone()
.into_iter()
.fold(0, |sum, item| sum + item.size_hint())
}
}
impl<'a, T> Type<Exasol> for &'a [T]
where
T: Type<Exasol> + 'a,
{
fn type_info() -> <Exasol as Database>::TypeInfo {
T::type_info()
}
fn compatible(ty: &<Exasol as Database>::TypeInfo) -> bool {
<Self as Type<Exasol>>::type_info().compatible(ty)
}
}
impl<T> Encode<'_, Exasol> for &[T]
where
for<'q> T: Encode<'q, Exasol> + Type<Exasol>,
{
fn produces(&self) -> Option<<Exasol as Database>::TypeInfo> {
self.first()
.and_then(Encode::produces)
.or_else(|| Some(T::type_info()))
}
fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
buf.append_iter(self.iter())?;
Ok(IsNull::No)
}
fn size_hint(&self) -> usize {
self.iter().fold(0, |sum, item| sum + item.size_hint())
}
}
impl<'a, T> Type<Exasol> for &'a mut [T]
where
T: Type<Exasol> + 'a,
{
fn type_info() -> <Exasol as Database>::TypeInfo {
T::type_info()
}
fn compatible(ty: &<Exasol as Database>::TypeInfo) -> bool {
<Self as Type<Exasol>>::type_info().compatible(ty)
}
}
impl<T> Encode<'_, Exasol> for &mut [T]
where
for<'q> T: Encode<'q, Exasol> + Type<Exasol>,
{
fn produces(&self) -> Option<<Exasol as Database>::TypeInfo> {
(&**self).produces()
}
fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
(&**self).encode_by_ref(buf)
}
fn size_hint(&self) -> usize {
(&**self).size_hint()
}
}
impl<T, const N: usize> Type<Exasol> for [T; N]
where
T: Type<Exasol>,
{
fn type_info() -> <Exasol as Database>::TypeInfo {
T::type_info()
}
fn compatible(ty: &<Exasol as Database>::TypeInfo) -> bool {
<Self as Type<Exasol>>::type_info().compatible(ty)
}
}
impl<T, const N: usize> Encode<'_, Exasol> for [T; N]
where
for<'q> T: Encode<'q, Exasol> + Type<Exasol>,
{
fn produces(&self) -> Option<<Exasol as Database>::TypeInfo> {
self.as_slice().produces()
}
fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
self.as_slice().encode_by_ref(buf)
}
fn size_hint(&self) -> usize {
self.as_slice().size_hint()
}
}
impl<T> Type<Exasol> for Vec<T>
where
T: Type<Exasol>,
{
fn type_info() -> <Exasol as Database>::TypeInfo {
T::type_info()
}
fn compatible(ty: &<Exasol as Database>::TypeInfo) -> bool {
<Self as Type<Exasol>>::type_info().compatible(ty)
}
}
impl<T> Encode<'_, Exasol> for Vec<T>
where
for<'q> T: Encode<'q, Exasol> + Type<Exasol>,
{
fn produces(&self) -> Option<<Exasol as Database>::TypeInfo> {
(&**self).produces()
}
fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
(&**self).encode_by_ref(buf)
}
fn size_hint(&self) -> usize {
(&**self).size_hint()
}
}
impl<T> Type<Exasol> for Box<[T]>
where
T: Type<Exasol>,
{
fn type_info() -> <Exasol as Database>::TypeInfo {
T::type_info()
}
fn compatible(ty: &<Exasol as Database>::TypeInfo) -> bool {
<Self as Type<Exasol>>::type_info().compatible(ty)
}
}
impl<T> Encode<'_, Exasol> for Box<[T]>
where
for<'q> T: Encode<'q, Exasol> + Type<Exasol>,
{
fn produces(&self) -> Option<<Exasol as Database>::TypeInfo> {
(&**self).produces()
}
fn encode_by_ref(&self, buf: &mut ExaBuffer) -> Result<IsNull, BoxDynError> {
(&**self).encode_by_ref(buf)
}
fn size_hint(&self) -> usize {
(&**self).size_hint()
}
}