diff --git a/Cargo.lock b/Cargo.lock index 267c59a..a9e4885 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -682,6 +682,8 @@ dependencies = [ "dyn-eq", "dyn-hash", "indexmap", + "serde", + "serde_json", "sqlx", "tokio", ] diff --git a/Cargo.toml b/Cargo.toml index b15bbe8..d5bbea0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,5 +10,7 @@ dyn-clone = "1.0.19" dyn-eq = "0.1.3" dyn-hash = "0.2.2" indexmap = "2.9.0" +serde = "1.0.219" +serde_json = "1.0.140" sqlx = { version = "0.8", features = [ "runtime-tokio", "sqlite" ] } tokio = { version = "1.45.0", features = ["full"] } diff --git a/src/main.rs b/src/main.rs index 9e011d3..a8430e3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,6 +20,7 @@ use chrono::NaiveDate; use libdrcr::db::DbConnection; use libdrcr::reporting::builders::register_dynamic_builders; use libdrcr::reporting::calculator::{steps_as_graphviz, steps_for_targets}; +use libdrcr::reporting::dynamic_report::DynamicReport; use libdrcr::reporting::generate_report; use libdrcr::reporting::steps::register_lookup_fns; use libdrcr::reporting::types::{ @@ -130,5 +131,8 @@ fn main() { .unwrap(); println!("Balance sheet:"); - println!("{:?}", result); + println!( + "{}", + result.downcast_ref::().unwrap().to_json() + ); } diff --git a/src/reporting/dynamic_report.rs b/src/reporting/dynamic_report.rs index 5ba208a..f08276a 100644 --- a/src/reporting/dynamic_report.rs +++ b/src/reporting/dynamic_report.rs @@ -18,12 +18,14 @@ use std::collections::HashMap; +use serde::{Deserialize, Serialize}; + use crate::QuantityInt; use super::types::{GenericReportingProduct, ReportingProduct}; /// Represents a dynamically generated report composed of [DynamicReportEntry] -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct DynamicReport { pub title: String, pub columns: Vec, @@ -109,20 +111,26 @@ impl DynamicReport { panic!("Called subtotal_for_id on non-Section"); } } + + /// Serialise the report (as JSON) using serde + pub fn to_json(&self) -> String { + serde_json::to_string(self).unwrap() + } } impl GenericReportingProduct for DynamicReport {} impl ReportingProduct for DynamicReport {} -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub enum DynamicReportEntry { Section(Section), LiteralRow(LiteralRow), + #[serde(skip)] CalculatedRow(CalculatedRow), Spacer, } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct Section { pub text: String, pub id: Option, @@ -230,7 +238,7 @@ impl Section { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct LiteralRow { pub text: String, pub quantity: Vec,