Skip to content

Commit 31f21e0

Browse files
nikomatsakisNiko Matsakis
andauthored
improve formatting (#248)
Co-authored-by: Niko Matsakis <nikomat@amazon.com>
1 parent 5c85bd2 commit 31f21e0

File tree

1 file changed

+43
-24
lines changed

1 file changed

+43
-24
lines changed

crates/rust-project-goals/src/format_team_ask.rs

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
use std::collections::BTreeSet;
1+
use std::{collections::{BTreeMap, BTreeSet}, path::PathBuf};
22

3-
use indexmap::IndexMap;
4-
5-
use crate::{config::Configuration, goal::TeamAsk, team::TeamName, util};
3+
use crate::{config::Configuration, goal::TeamAsk, team::TeamName, util::{self, ARROW}};
64

75
/// Format a set of team asks into a table, with asks separated by team and grouped by kind.
86
///
@@ -65,22 +63,11 @@ pub fn format_team_asks(asks_of_any_team: &[&TeamAsk]) -> anyhow::Result<String>
6563
};
6664

6765
// Collect the asks by goal. The `rows` map goes from goal title to a row with entries
68-
let mut goal_rows: IndexMap<String, Vec<String>> = IndexMap::default();
66+
let mut goal_rows: BTreeMap<GoalData<'_>, Vec<String>> = BTreeMap::default();
6967
for ask in &asks_of_this_team {
70-
let link = format!("{}", ask.link_path.display());
71-
72-
let goal_title = match &ask.goal_titles[..] {
73-
[goal_title] => format!("[{goal_title}]({link}#ownership-and-team-asks)"),
74-
[goal_title, subgoal_title] => {
75-
format!("[{subgoal_title}]({link}#ownership-and-team-asks) (part of [{goal_title}]({link}))")
76-
}
77-
_ => anyhow::bail!(
78-
"expected either 1 or 2 goal titles, not {:?}",
79-
ask.goal_titles
80-
),
81-
};
68+
let goal_data = GoalData::new(ask)?;
8269

83-
let row = goal_rows.entry(goal_title).or_insert_with(empty_row);
70+
let row = goal_rows.entry(goal_data).or_insert_with(empty_row);
8471

8572
let index = ask_headings
8673
.iter()
@@ -110,10 +97,12 @@ pub fn format_team_asks(asks_of_any_team: &[&TeamAsk]) -> anyhow::Result<String>
11097
}
11198
}
11299

113-
// Sort the goal rows by name (ignoring case).
114-
goal_rows.sort_by_cached_key(|ask_names, _ask_rows| {
115-
ask_names.clone().to_uppercase()
116-
});
100+
// Ensure that we have an entry for the "meta-goal", even if there are no asks.
101+
for ask in &asks_of_this_team {
102+
let mut goal_data = GoalData::new(ask)?;
103+
goal_data.subgoal_title = None;
104+
goal_rows.entry(goal_data).or_insert_with(empty_row);
105+
}
117106

118107
// Create the table itself.
119108
let table = {
@@ -128,8 +117,8 @@ pub fn format_team_asks(asks_of_any_team: &[&TeamAsk]) -> anyhow::Result<String>
128117
) // e.g. "discussion and moral support"
129118
.collect::<Vec<String>>();
130119

131-
let rows = goal_rows.into_iter().map(|(goal_title, goal_columns)| {
132-
std::iter::once(goal_title)
120+
let rows = goal_rows.into_iter().map(|(goal_data, goal_columns)| {
121+
std::iter::once(goal_data.goal_title())
133122
.chain(goal_columns)
134123
.collect::<Vec<String>>()
135124
});
@@ -146,3 +135,33 @@ pub fn format_team_asks(asks_of_any_team: &[&TeamAsk]) -> anyhow::Result<String>
146135

147136
Ok(output)
148137
}
138+
139+
#[derive(Eq, PartialEq, PartialOrd, Ord, Hash, Copy, Clone, Debug)]
140+
struct GoalData<'g> {
141+
goal_title: &'g String,
142+
subgoal_title: Option<&'g String>,
143+
link: &'g PathBuf,
144+
}
145+
146+
impl<'g> GoalData<'g> {
147+
fn new(ask: &'g TeamAsk) -> anyhow::Result<Self> {
148+
match &ask.goal_titles[..] {
149+
[goal_title] => Ok(Self { goal_title, subgoal_title: None, link: &ask.link_path }),
150+
[goal_title, subgoal_title] => {
151+
Ok(Self { goal_title, subgoal_title: Some(subgoal_title), link: &ask.link_path })
152+
}
153+
_ => anyhow::bail!(
154+
"expected either 1 or 2 goal titles, not {:?}",
155+
ask.goal_titles
156+
),
157+
}
158+
}
159+
160+
fn goal_title(&self) -> String {
161+
if let Some(subgoal_title) = self.subgoal_title {
162+
format!("{} {}", ARROW, subgoal_title)
163+
} else {
164+
format!("[{}]({})", self.goal_title, self.link.display())
165+
}
166+
}
167+
}

0 commit comments

Comments
 (0)