refactor: eliminate Box<dyn Iterator> and Option sentinels in export_csv
The CSV export used Box<dyn Iterator<Item = Option<usize>>> to unify empty and non-empty row iteration, violating the CLAUDE.md rule that Box/Rc container management should be split from logic. Replaced with a direct for loop over row indices, removing both the Box and the Option sentinels used to represent "placeholder empty row/col". Also removes unused pub use cell::CellKey re-export and an unused import in cell.rs tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@ -143,7 +143,7 @@ impl DataStore {
|
||||
|
||||
#[cfg(test)]
|
||||
mod cell_key {
|
||||
use super::{CellKey, CellValue, DataStore};
|
||||
use super::CellKey;
|
||||
|
||||
fn key(pairs: &[(&str, &str)]) -> CellKey {
|
||||
CellKey::new(pairs.iter().map(|(c, i)| (c.to_string(), i.to_string())).collect())
|
||||
|
||||
@ -2,5 +2,4 @@ pub mod category;
|
||||
pub mod cell;
|
||||
pub mod model;
|
||||
|
||||
pub use cell::CellKey;
|
||||
pub use model::Model;
|
||||
|
||||
@ -79,33 +79,19 @@ pub fn export_csv(model: &Model, view_name: &str, path: &Path) -> Result<()> {
|
||||
out.push_str(&col_labels.join(","));
|
||||
out.push('\n');
|
||||
|
||||
// Data rows — treat zero-item axes as a single empty placeholder row/col
|
||||
let row_range: Box<dyn Iterator<Item = Option<usize>>> = if layout.row_count() == 0 {
|
||||
Box::new(std::iter::once(None))
|
||||
} else {
|
||||
Box::new((0..layout.row_count()).map(Some))
|
||||
};
|
||||
let col_indices: Vec<Option<usize>> = if layout.col_count() == 0 {
|
||||
vec![None]
|
||||
} else {
|
||||
(0..layout.col_count()).map(Some).collect()
|
||||
};
|
||||
|
||||
for row_opt in row_range {
|
||||
let row_label = row_opt.map(|ri| layout.row_label(ri)).unwrap_or_default();
|
||||
// Data rows
|
||||
for ri in 0..layout.row_count() {
|
||||
let row_label = layout.row_label(ri);
|
||||
if !row_label.is_empty() {
|
||||
out.push_str(&row_label);
|
||||
out.push(',');
|
||||
}
|
||||
let row_values: Vec<String> = col_indices.iter().map(|&col_opt| {
|
||||
match (row_opt, col_opt) {
|
||||
(Some(ri), Some(ci)) => layout.cell_key(ri, ci)
|
||||
let row_values: Vec<String> = (0..layout.col_count())
|
||||
.map(|ci| layout.cell_key(ri, ci)
|
||||
.and_then(|key| model.evaluate(&key))
|
||||
.map(|v| v.to_string())
|
||||
.unwrap_or_default(),
|
||||
_ => String::new(),
|
||||
}
|
||||
}).collect();
|
||||
.unwrap_or_default())
|
||||
.collect();
|
||||
out.push_str(&row_values.join(","));
|
||||
out.push('\n');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user