use std::{fmt::Debug, sync::Arc};
use hyphae::CellImmutable;
use serde::{Serialize, de::DeserializeOwned};
use serde_json::Value;
use super::{
super::item::{AnyItem, Eventable},
context::QueryContext,
request::QueryRequest,
};
#[cfg(not(target_arch = "wasm32"))]
use crate::core::query::QueryCellContext;
#[cfg(not(target_arch = "wasm32"))]
use crate::core::query::cell::FilteredCellMap;
use crate::{
cache::CacheKey,
client::MykoClient,
common::{with_id::WithId, with_transaction::WithTransaction},
prelude::WithTypedId,
wire::WrappedQuery,
};
pub trait QueryId {
fn query_id(&self) -> Arc<str>;
}
pub trait QueryIdStatic {
fn query_id_static() -> Arc<str>;
}
pub trait QueryItemType {
type Item: WithTypedId + std::fmt::Debug + PartialEq + Send + Sync;
fn query_item_type(&self) -> Arc<str>;
fn query_item_type_static() -> Arc<str>;
}
pub trait QueryHandler: QueryItemType + Sized {
fn test_entity(ctx: QueryTestCtx<Self>) -> bool
where
Self: Send + Sync + 'static;
#[cfg(not(target_arch = "wasm32"))]
fn build_view(_ctx: QueryBuildCellCtx<Self>) -> Option<FilteredCellMap>
where
Self: Send + Sync + 'static,
{
None
}
}
pub struct QueryTestCtx<TQuery: QueryItemType> {
pub item: Arc<TQuery::Item>,
pub query: Arc<TQuery>,
pub query_context: Arc<QueryContext>,
}
impl<TQuery: QueryItemType> QueryTestCtx<TQuery> {
pub fn map_bool<F>(self, predicate: F) -> bool
where
F: Fn(QueryTestCtx<TQuery>) -> bool,
{
predicate(self)
}
}
#[cfg(not(target_arch = "wasm32"))]
pub struct QueryBuildCellCtx<TQuery: QueryItemType> {
pub query: Arc<TQuery>,
pub query_context: QueryCellContext,
}
#[derive(Debug)]
#[allow(dead_code)]
pub struct QueryHandlerCtxAny {
pub item: Arc<dyn AnyItem>,
pub query: Arc<dyn AnyQuery>,
pub ctx: Arc<QueryContext>,
}
pub trait QueryParams:
CacheKey
+ Serialize
+ DeserializeOwned
+ Clone
+ Send
+ Sync
+ QueryId
+ QueryIdStatic
+ QueryItemType
+ QueryHandler
+ std::fmt::Debug
+ 'static
{
}
impl<T> QueryParams for T where
T: Serialize
+ CacheKey
+ DeserializeOwned
+ Clone
+ Send
+ Sync
+ QueryId
+ QueryIdStatic
+ QueryItemType
+ QueryHandler
+ std::fmt::Debug
+ 'static
{
}
pub trait Query:
Serialize
+ DeserializeOwned
+ Send
+ Sync
+ QueryId
+ QueryIdStatic
+ QueryItemType
+ QueryHandler
+ WithTransaction
+ AnyQuery
+ 'static
{
type Params: QueryParams;
fn watch(
&self,
client: &MykoClient,
) -> hyphae::Cell<Vec<Arc<<Self as QueryItemType>::Item>>, CellImmutable>;
}
impl<Q: QueryParams + Clone> Query for QueryRequest<Q>
where
Q::Item:
Eventable + WithId + DeserializeOwned + Clone + std::fmt::Debug + Send + Sync + 'static,
{
type Params = Q;
fn watch(
&self,
client: &MykoClient,
) -> hyphae::Cell<Vec<Arc<<Self as QueryItemType>::Item>>, CellImmutable> {
client.watch_query::<Q>(self)
}
}
pub trait AnyQuery: WithTransaction + QueryId + Debug + Send + Sync + 'static {
fn query_item_type(&self) -> Arc<str>;
fn to_value(&self) -> Value;
}
impl From<&dyn AnyQuery> for WrappedQuery {
fn from(query: &dyn AnyQuery) -> Self {
WrappedQuery {
query: query.to_value(),
query_id: query.query_id(),
query_item_type: query.query_item_type(),
window: None,
}
}
}
impl From<Arc<dyn AnyQuery>> for WrappedQuery {
fn from(query: Arc<dyn AnyQuery>) -> Self {
WrappedQuery::from(query.as_ref())
}
}
impl From<&Arc<dyn AnyQuery>> for WrappedQuery {
fn from(query: &Arc<dyn AnyQuery>) -> Self {
WrappedQuery::from(query.as_ref())
}
}