use std::sync::Arc;
#[cfg(feature = "typed")]
use schemars::SchemaGenerator;
use crate::{
callable::{BoxedCallable, CallableFetch},
store::StoreId,
App, Store, StoreData, StoreMut, StoreRef, User, Users,
};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct SelectKey(pub(crate) Arc<str>);
#[allow(unused)]
pub struct AnySelect {
pub(crate) name: SelectKey,
pub(crate) select: BoxedCallable<SelectContext, serde_json::Value, serde_json::Error>,
#[cfg(feature = "typed")]
pub(crate) desc:
Arc<dyn Fn(&mut SchemaGenerator) -> crate::typed::StoreDesc + Send + Sync + 'static>,
}
pub struct SelectContext {
pub(crate) app: App,
pub(crate) user: User,
}
impl CallableFetch<App> for SelectContext {
fn fetch(&self) -> App {
self.app.clone()
}
}
impl CallableFetch<User> for SelectContext {
fn fetch(&self) -> User {
self.user.clone()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum SelectDependencyType {
Store(StoreId),
Users,
None,
}
pub(crate) trait SelectDependency {
fn depends_on() -> SelectDependencyType {
SelectDependencyType::None
}
}
impl<T> SelectDependency for Store<T>
where
T: StoreData,
{
fn depends_on() -> SelectDependencyType {
SelectDependencyType::Store(StoreId::of::<T>())
}
}
impl<T> SelectDependency for StoreRef<T>
where
T: StoreData,
{
fn depends_on() -> SelectDependencyType {
SelectDependencyType::Store(StoreId::of::<T>())
}
}
impl<T> SelectDependency for StoreMut<T>
where
T: StoreData,
{
fn depends_on() -> SelectDependencyType {
SelectDependencyType::Store(StoreId::of::<T>())
}
}
impl SelectDependency for Users {
fn depends_on() -> SelectDependencyType {
SelectDependencyType::Users
}
}
macro_rules! impl_not_dependency {
($($t:ty),+) => {
$(impl SelectDependency for $t {})+
};
}
impl_not_dependency!(App, User);
pub trait GetParamSelectDependencies<const N: usize> {
fn get_select_dependencies() -> [SelectDependencyType; N];
}
macro_rules! extract_select_dependency {
($n:expr, $($members:ident),+) => {
impl<
$($members),+
> GetParamSelectDependencies<$n>
for ($($members,)+)
where
$($members: SelectDependency),+
{
#[inline(always)]
fn get_select_dependencies() -> [SelectDependencyType; $n] {
[
$($members::depends_on()),+,
]
}
}
};
}
impl GetParamSelectDependencies<0> for () {
#[inline(always)]
fn get_select_dependencies() -> [SelectDependencyType; 0] {
[]
}
}
extract_select_dependency!(1, T1);
extract_select_dependency!(2, T1, T2);
extract_select_dependency!(3, T1, T2, T3);
extract_select_dependency!(4, T1, T2, T3, T4);
extract_select_dependency!(5, T1, T2, T3, T4, T5);
extract_select_dependency!(6, T1, T2, T3, T4, T5, T6);
extract_select_dependency!(7, T1, T2, T3, T4, T5, T6, T7);
extract_select_dependency!(8, T1, T2, T3, T4, T5, T6, T7, T8);