use std::{fmt::Debug, sync::Arc};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use ts_rs::TS;
use uuid::Uuid;
use super::traits::{AnyReport, ReportId, ReportIdStatic, ReportOutputType, ReportParams};
use crate::common::with_transaction::WithTransaction;
#[derive(Clone, Debug, Serialize, Deserialize, TS)]
#[serde(rename_all = "camelCase")]
pub struct ReportRequest<R> {
pub tx: Arc<str>,
#[serde(flatten)]
pub report: R,
}
impl<R> ReportRequest<R> {
pub fn new(report: R) -> Self {
Self {
tx: Uuid::new_v4().to_string().into(),
report,
}
}
pub fn with_tx(report: R, tx: Arc<str>) -> Self {
Self { tx, report }
}
}
impl<R: Default> Default for ReportRequest<R> {
fn default() -> Self {
Self::new(R::default())
}
}
impl<R: ReportParams> From<R> for ReportRequest<R> {
fn from(report: R) -> Self {
Self::new(report)
}
}
impl<R: Clone> From<&ReportRequest<R>> for ReportRequest<R> {
fn from(request: &ReportRequest<R>) -> Self {
request.clone()
}
}
impl<R: Send + Sync + 'static> WithTransaction for ReportRequest<R> {
fn tx_id(&self) -> Arc<str> {
self.tx.clone()
}
}
impl<R: ReportId> ReportId for ReportRequest<R> {
fn report_id(&self) -> Arc<str> {
self.report.report_id()
}
}
impl<R: ReportIdStatic> ReportIdStatic for ReportRequest<R> {
fn report_id_static() -> &'static str {
R::report_id_static()
}
}
impl<R: ReportOutputType> ReportOutputType for ReportRequest<R> {
type Output = R::Output;
}
impl<R: ReportId + Serialize + Debug + Send + Sync + 'static> AnyReport for ReportRequest<R> {
fn to_value(&self) -> Value {
serde_json::to_value(self).expect("ReportRequest should serialize to JSON")
}
}