Panics · P14 Tables: pivots, groupings and merges that name what their data lost log instead of panicking

This commit is contained in:
ZacharyZhang-NY committed 2026-10-06 17:47:24 -04:00
1 parent f2fc17118c
commit 2ea16f4541
6 files changed
+62 -18

No files matched your search

+17 -8
View File
@@ -130,16 +130,24 @@ impl PivotTable {
impl RenderOnce for PivotTable {
fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
let field = |name: &SharedString| {
self.fields
.iter()
.position(|known| known == name)
.unwrap_or_else(|| panic!("no field {name} to pivot by"))
};
let (down, across, value) = (field(&self.by.0), field(&self.by.1), field(&self.by.2));
let table = pivot(&self.records, down, across, value, self.how);
let field = |name: &SharedString| self.fields.iter().position(|known| known == name);
let theme = cx.theme();
let colors = &theme.colors;
let (Some(down), Some(across), Some(value)) =
(field(&self.by.0), field(&self.by.1), field(&self.by.2))
else {
let (down, across, value) = &self.by;
log::error!(
"pivot table: {down}, {across} or {value} is not among {:?}",
self.fields
);
return div()
.text_size(theme.text_size(TextSize::Sm))
.text_color(colors.danger)
.child(format!("No field to pivot by {down}, {across} and {value}"))
.into_any_element();
};
let table = pivot(&self.records, down, across, value, self.how);
let decimals = self.decimals;
let reads = |figure: Option<f64>| {
figure.map_or("—".to_string(), |figure| {
@@ -205,6 +213,7 @@ impl RenderOnce for PivotTable {
.child(head)
.children(body)
.child(totals)
.into_any_element()
}
}
+4 -4
View File
@@ -113,10 +113,10 @@ impl Spreadsheet {
from.0 <= to.0 && from.1 <= to.1,
"a merge runs from its top-left to its bottom-right"
);
assert!(
to.0 < self.size.0 && to.1 < self.size.1,
"a merge stays inside the sheet"
);
if to.0 >= self.size.0 || to.1 >= self.size.1 {
log::error!("sheet: a merge to {to:?} leaves {:?}; skipped", self.size);
return self;
}
self.merges.push(Merge { from, to });
self
}
+7 -5
View File
@@ -191,11 +191,13 @@ impl RenderOnce for DataTable {
lines.push(Line::Detail { ix });
}
};
match self
.group_by
.as_ref()
.map(|key| index(key).unwrap_or_else(|| panic!("no column {key} to group by")))
{
match self.group_by.as_ref().and_then(|key| {
let col = index(key);
if col.is_none() {
log::error!("data table {id:?}: no column {key} to group by; ungrouped");
}
col
}) {
Some(col) => {
for (name, members) in groups(&rows, &order, col) {
let shut = folded.contains(&name);
+1
View File
@@ -11,6 +11,7 @@ use gpui::{
mod clipboard;
mod columns;
mod stale;
use super::{Column, DataTable, FilterBuilder, FilterRule, Row};
use crate::{
+31
View File
@@ -0,0 +1,31 @@
use gpui::{Context, IntoElement, ParentElement, Render, Styled, TestAppContext, Window, div, px};
use crate::{
tables::{Aggregate, Column, DataTable, PivotTable, Row, Spreadsheet},
theme::Theme,
};
/// A pivot, a grouping and a merge that name what their data no longer holds.
struct Stale;
impl Render for Stale {
fn render(&mut self, _: &mut Window, _: &mut Context<Self>) -> impl IntoElement {
let pivot = PivotTable::new(["region", "sales"], [vec!["Europe".into(), 4.0.into()]])
.pivot("region", "quarter", "sales", Aggregate::Sum);
let table = DataTable::new("table", [Column::new("name", "Name")])
.rows(vec![Row::new("a", ["Ann".into()])])
.group_by("region");
let sheet = Spreadsheet::new("sheet", 2, 2)
.merge((0, 0), (5, 1))
.w(px(300.0))
.h(px(120.0));
div().w(px(400.0)).child(pivot).child(table).child(sheet)
}
}
#[gpui::test]
fn a_pivot_grouping_or_merge_past_its_data_draws(cx: &mut TestAppContext) {
cx.update(Theme::init);
let (_, cx) = cx.add_window_view(|_, _| Stale);
cx.run_until_parked();
}