chore: reformat

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Edward Langley
2026-03-31 00:07:22 -07:00
parent 37584670eb
commit 183b2350f7
17 changed files with 1112 additions and 471 deletions

View File

@ -1,5 +1,5 @@
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
/// A cell key is a sorted vector of (category_name, item_name) pairs.
/// Sorted by category name for canonical form.
@ -13,7 +13,10 @@ impl CellKey {
}
pub fn get(&self, category: &str) -> Option<&str> {
self.0.iter().find(|(c, _)| c == category).map(|(_, v)| v.as_str())
self.0
.iter()
.find(|(c, _)| c == category)
.map(|(_, v)| v.as_str())
}
pub fn with(mut self, category: impl Into<String>, item: impl Into<String>) -> Self {
@ -29,11 +32,19 @@ impl CellKey {
}
pub fn without(&self, category: &str) -> Self {
Self(self.0.iter().filter(|(c, _)| c != category).cloned().collect())
Self(
self.0
.iter()
.filter(|(c, _)| c != category)
.cloned()
.collect(),
)
}
pub fn matches_partial(&self, partial: &[(String, String)]) -> bool {
partial.iter().all(|(cat, item)| self.get(cat) == Some(item.as_str()))
partial
.iter()
.all(|(cat, item)| self.get(cat) == Some(item.as_str()))
}
}
@ -123,7 +134,8 @@ impl DataStore {
/// All cells where partial coords match
pub fn matching_cells(&self, partial: &[(String, String)]) -> Vec<(&CellKey, &CellValue)> {
self.cells.iter()
self.cells
.iter()
.filter(|(key, _)| key.matches_partial(partial))
.collect()
}
@ -134,12 +146,21 @@ mod cell_key {
use super::CellKey;
fn key(pairs: &[(&str, &str)]) -> CellKey {
CellKey::new(pairs.iter().map(|(c, i)| (c.to_string(), i.to_string())).collect())
CellKey::new(
pairs
.iter()
.map(|(c, i)| (c.to_string(), i.to_string()))
.collect(),
)
}
#[test]
fn coords_are_sorted_by_category_name() {
let k = key(&[("Region", "East"), ("Measure", "Revenue"), ("Product", "Shirts")]);
let k = key(&[
("Region", "East"),
("Measure", "Revenue"),
("Product", "Shirts"),
]);
assert_eq!(k.0[0].0, "Measure");
assert_eq!(k.0[1].0, "Product");
assert_eq!(k.0[2].0, "Region");
@ -227,7 +248,12 @@ mod data_store {
use super::{CellKey, CellValue, DataStore};
fn key(pairs: &[(&str, &str)]) -> CellKey {
CellKey::new(pairs.iter().map(|(c, i)| (c.to_string(), i.to_string())).collect())
CellKey::new(
pairs
.iter()
.map(|(c, i)| (c.to_string(), i.to_string()))
.collect(),
)
}
#[test]
@ -265,9 +291,18 @@ mod data_store {
#[test]
fn matching_cells_returns_correct_subset() {
let mut store = DataStore::new();
store.set(key(&[("Measure", "Revenue"), ("Region", "East")]), CellValue::Number(100.0));
store.set(key(&[("Measure", "Revenue"), ("Region", "West")]), CellValue::Number(200.0));
store.set(key(&[("Measure", "Cost"), ("Region", "East")]), CellValue::Number(50.0));
store.set(
key(&[("Measure", "Revenue"), ("Region", "East")]),
CellValue::Number(100.0),
);
store.set(
key(&[("Measure", "Revenue"), ("Region", "West")]),
CellValue::Number(200.0),
);
store.set(
key(&[("Measure", "Cost"), ("Region", "East")]),
CellValue::Number(50.0),
);
let partial = vec![("Measure".to_string(), "Revenue".to_string())];
let cells = store.matching_cells(&partial);
assert_eq!(cells.len(), 2);
@ -275,13 +310,12 @@ mod data_store {
assert!(values.contains(&100.0));
assert!(values.contains(&200.0));
}
}
#[cfg(test)]
mod prop_tests {
use proptest::prelude::*;
use super::{CellKey, CellValue, DataStore};
use proptest::prelude::*;
/// Strategy: map of unique cat→item strings (HashMap guarantees unique keys).
fn pairs_map() -> impl Strategy<Value = Vec<(String, String)>> {