use std::{fmt::Debug, sync::Arc};
use hyphae::CellImmutable;
use serde::{Serialize, de::DeserializeOwned};
use serde_json::Value;
use ts_rs::TS;
use super::{handler::ReportHandler, request::ReportRequest};
use crate::{
cache::CacheKey, client::MykoClient, common::with_transaction::WithTransaction,
wire::WrappedReport,
};
pub trait ReportId {
fn report_id(&self) -> Arc<str>;
}
pub trait ReportIdStatic {
fn report_id_static() -> &'static str;
}
pub trait ReportOutputType {
type Output: Serialize + DeserializeOwned + Clone + Debug + PartialEq + Send + Sync + 'static;
}
pub trait MykoReport<T> {
fn watch(&self, client: &MykoClient) -> hyphae::Cell<Option<T>, CellImmutable>;
}
#[derive(Debug, Clone)]
pub enum ReportOutput {
Value(Value),
Error(String),
}
pub trait AnyReport: WithTransaction + ReportId + Debug + Send + Sync + 'static {
fn to_value(&self) -> Value;
}
impl From<&dyn AnyReport> for WrappedReport {
fn from(report: &dyn AnyReport) -> Self {
WrappedReport {
report: report.to_value(),
report_id: report.report_id().to_string(),
}
}
}
impl From<Arc<dyn AnyReport>> for WrappedReport {
fn from(report: Arc<dyn AnyReport>) -> Self {
WrappedReport::from(report.as_ref())
}
}
impl From<&Arc<dyn AnyReport>> for WrappedReport {
fn from(report: &Arc<dyn AnyReport>) -> Self {
WrappedReport::from(report.as_ref())
}
}
pub trait ReportParams:
CacheKey
+ Serialize
+ DeserializeOwned
+ Clone
+ Send
+ Sync
+ ReportId
+ ReportIdStatic
+ ReportOutputType
+ ReportHandler
+ Debug
+ 'static
{
}
impl<T> ReportParams for T where
T: Serialize
+ CacheKey
+ DeserializeOwned
+ Clone
+ Send
+ Sync
+ ReportId
+ ReportIdStatic
+ ReportOutputType
+ ReportHandler
+ Debug
+ 'static
{
}
pub trait Report:
Serialize
+ DeserializeOwned
+ Send
+ Sync
+ ReportId
+ ReportIdStatic
+ ReportOutputType
+ WithTransaction
+ AnyReport
+ 'static
{
type Params: ReportParams;
fn watch(
&self,
client: &MykoClient,
) -> hyphae::Cell<Option<<Self as ReportOutputType>::Output>, CellImmutable>;
}
impl<R: ReportParams> Report for ReportRequest<R> {
type Params = R;
fn watch(
&self,
client: &MykoClient,
) -> hyphae::Cell<Option<<Self as ReportOutputType>::Output>, CellImmutable> {
client.watch_report::<R, <R as ReportOutputType>::Output>(self)
}
}
#[derive(Debug, Clone, PartialEq, Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct CountResult {
pub count: usize,
}