1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//! Export module for simulation results.
//!
//! # Architecture
//!
//! This module defines the [`Exporter`] trait that abstracts the export format.
//! Each format is an independent implementation in its own sub-module.
//! This design follows the **Open/Closed principle**: adding a new format
//! means adding a file, without ever modifying existing code.
//!
//! # Available formats
//!
//! | Format | Module | Version |
//! |---------|-----------------|---------|
//! | CSV | [`csv`] | v0.1.0 |
//! | ODS | `ods` (future) | v0.2.0 |
//! | Scilab | `scilab` (future)| v0.2.0 |
//! | Matlab | `matlab` (future)| v0.2.0 |
//!
//! # Usage example
//!
//! ```rust
//! use chrom_rs::output::export::csv::CsvExporter;
//! use chrom_rs::output::export::Exporter;
//! use chrom_rs::solver::SimulationResult;
//! use chrom_rs::physics::{PhysicalState, PhysicalQuantity, PhysicalData};
//!
//! let exporter = CsvExporter::default();
//!
//! // Create a dummy result for demonstration
//! let state = PhysicalState::new(
//! PhysicalQuantity::Concentration,
//! PhysicalData::Scalar(0.0)
//! );
//! let result = SimulationResult::new(
//! vec![0.0, 1.0],
//! vec![state.clone(), state.clone()],
//! state
//! );
//!
//! // Full export (all time steps)
//! exporter.export_single(&result, None, "/tmp/tfa.csv");
//!
//! // Downsampled export to 500 points
//! exporter.export_single(&result, Some(500), "/tmp/tfa_light.csv");
//!
//! // Multi-species export with labels
//! exporter.export_multi(&result, None, &["Ascorbic", "Erythorbic"], "/tmp/acids.csv");
//! ```
// Re-export the most commonly used types at the module level so users can write:
// use chrom_rs::output::export::{CsvExporter, CsvConfig, CsvError};
// instead of the full sub-module path.
use crateSimulationResult;
pub use ;
pub use ;
/// Abstraction trait for all export formats.
///
/// # Associated type `Error`
///
/// Each format manages its own errors via the associated type.
/// This avoids systematic boxing (`Box<dyn Error>`) and allows
/// the caller to react precisely based on the error type.
///
/// # Parameter `n_points`
///
/// - `None`: exports all time steps (default behaviour)
/// - `Some(n)`: uniformly downsamples to `n` points,
/// always guaranteeing that the **first and last** points
/// are included (important to capture the end of the chromatographic peak)
///
/// # Implementing this trait
///
/// A new format must implement `export_single` and `export_multi`.
/// Formats that do not distinguish between the two cases can delegate one to the other.