kosame 0.3.0

Macro-based Rust ORM focused on developer ergonomics
Documentation
mod runner;

pub use kosame_repr::query::*;
pub use runner::*;

use crate::{Error, driver::Connection, params::Params};
use pollster::FutureExt;

pub trait Query {
    type Params: std::fmt::Debug;
    type Row;

    const REPR: Node<'static>;

    fn repr(&self) -> &'static Node<'static> {
        &Self::REPR
    }

    fn params(&self) -> &Self::Params;

    fn query_vec<'c, C>(
        &self,
        connection: &mut C,
    ) -> impl Future<Output = crate::Result<Vec<Self::Row>>>
    where
        C: Connection,
        Self::Params: Params<C::Params<'c>>,
        for<'b> Self::Row: From<&'b C::Row>,
    {
        async { RecordArrayRunner {}.run(connection, self).await }
    }

    fn query_one<'c, C>(&self, connection: &mut C) -> impl Future<Output = crate::Result<Self::Row>>
    where
        C: Connection,
        Self::Params: Params<C::Params<'c>>,
        for<'b> Self::Row: From<&'b C::Row>,
    {
        async {
            self.query_opt(connection)
                .await
                .and_then(|res| res.ok_or(Error::RowCount))
        }
    }

    fn query_opt<'c, C>(
        &self,
        connection: &mut C,
    ) -> impl Future<Output = crate::Result<Option<Self::Row>>>
    where
        C: Connection,
        Self::Params: Params<C::Params<'c>>,
        for<'b> Self::Row: From<&'b C::Row>,
    {
        async {
            self.query_vec(connection).await.and_then(|res| {
                let mut iter = res.into_iter();
                let row = iter.next();
                if row.is_some() && iter.next().is_some() {
                    return Err(Error::RowCount);
                }
                Ok(row)
            })
        }
    }

    fn query_vec_sync<'c, C>(&self, connection: &mut C) -> crate::Result<Vec<Self::Row>>
    where
        C: Connection,
        Self::Params: Params<C::Params<'c>>,
        for<'b> Self::Row: From<&'b C::Row>,
    {
        self.query_vec(connection).block_on()
    }

    fn query_one_sync<'c, C>(&self, connection: &mut C) -> crate::Result<Self::Row>
    where
        C: Connection,
        Self::Params: Params<C::Params<'c>>,
        for<'b> Self::Row: From<&'b C::Row>,
    {
        self.query_one(connection).block_on()
    }

    fn query_opt_sync<'c, C>(&self, connection: &mut C) -> crate::Result<Option<Self::Row>>
    where
        C: Connection,
        Self::Params: Params<C::Params<'c>>,
        for<'b> Self::Row: From<&'b C::Row>,
    {
        self.query_opt(connection).block_on()
    }
}