@@ -71,15 +71,11 @@ impl RustTeams {
7171 . filter ( |team| team. website_data . is_some ( ) )
7272 // On the main page, show the leadership-council and all top-level
7373 // teams.
74- . filter ( |team| team . kind == TeamKind :: Team && team . subteam_of . is_none ( ) )
74+ . filter ( |team| is_toplevel_team ( team ) )
7575 . map ( |team| IndexTeam {
7676 section : kind_to_str ( team. kind ) ,
7777 page_name : team. website_data . clone ( ) . unwrap ( ) . page ,
78- url : format ! (
79- "{}/{}" ,
80- kind_to_str( team. kind) ,
81- team. website_data. as_ref( ) . unwrap( ) . page
82- ) ,
78+ url : get_team_relative_url ( & team) ,
8379 team,
8480 } )
8581 . collect :: < Vec < IndexTeam > > ( ) ;
@@ -234,6 +230,113 @@ impl RustTeams {
234230
235231 AllTeamMembers { active, alumni }
236232 }
233+
234+ pub fn all_person_data ( & self ) -> Vec < PersonData > {
235+ let mut people: HashMap < String , PersonData > = HashMap :: new ( ) ;
236+
237+ enum TeamMode {
238+ Member ,
239+ Alumni ,
240+ MemberOfArchivedTeam ,
241+ }
242+
243+ fn add_team (
244+ people : & mut HashMap < String , PersonData > ,
245+ ctx : & RustTeams ,
246+ member : & TeamMember ,
247+ team : & Team ,
248+ mode : TeamMode ,
249+ ) {
250+ let person = people
251+ . entry ( member. github . clone ( ) )
252+ . or_insert_with ( move || PersonData {
253+ name : member. name . clone ( ) ,
254+ github : member. github . clone ( ) ,
255+ active_teams : vec ! [ ] ,
256+ alumni_teams : vec ! [ ] ,
257+ } ) ;
258+ let teams = match mode {
259+ TeamMode :: Member => & mut person. active_teams ,
260+ TeamMode :: Alumni | TeamMode :: MemberOfArchivedTeam => & mut person. alumni_teams ,
261+ } ;
262+ let url = match mode {
263+ TeamMode :: Member | TeamMode :: Alumni => ctx. get_toplevel_team_url ( team) ,
264+ TeamMode :: MemberOfArchivedTeam => Some ( "archived-teams.html" . to_string ( ) ) ,
265+ } ;
266+ teams. push ( PersonTeam :: new ( team, url) ) ;
267+ }
268+
269+ for team in & self . archived_teams {
270+ for member in team. members . iter ( ) . chain ( & team. alumni ) {
271+ add_team (
272+ & mut people,
273+ self ,
274+ member,
275+ team,
276+ TeamMode :: MemberOfArchivedTeam ,
277+ ) ;
278+ }
279+ }
280+ for team in & self . teams {
281+ if team. name == "all" || team. name == "alumni" || team. name == "leads" {
282+ continue ;
283+ }
284+
285+ for member in & team. members {
286+ add_team ( & mut people, self , member, team, TeamMode :: Member ) ;
287+ }
288+ for member in & team. alumni {
289+ add_team ( & mut people, self , member, team, TeamMode :: Alumni ) ;
290+ }
291+ }
292+
293+ let mut people: Vec < PersonData > = people. into_values ( ) . collect ( ) ;
294+ people. sort_by ( |a, b| a. github . cmp ( & b. github ) ) ;
295+
296+ for person in & mut people {
297+ person
298+ . active_teams
299+ . sort_by ( |a, b| a. webpage_name . cmp ( & b. webpage_name ) ) ;
300+ person
301+ . alumni_teams
302+ . sort_by ( |a, b| a. webpage_name . cmp ( & b. webpage_name ) ) ;
303+ }
304+
305+ people
306+ }
307+
308+ fn get_toplevel_team_url < ' a > ( & ' a self , mut team : & ' a Team ) -> Option < String > {
309+ while !is_toplevel_team ( team) {
310+ let Some ( parent) = & team. subteam_of else {
311+ return None ;
312+ } ;
313+ let Some ( parent) = self . teams . iter ( ) . find ( |t| t. name == * parent) else {
314+ return None ;
315+ } ;
316+ team = parent;
317+ }
318+
319+ if team. website_data . is_some ( ) {
320+ Some ( get_team_relative_url ( team) )
321+ } else {
322+ None
323+ }
324+ }
325+ }
326+
327+ /// Get a relative URL of a team that should be appended to
328+ /// Should only be used for top-level teams.
329+ fn get_team_relative_url ( team : & Team ) -> String {
330+ assert ! ( is_toplevel_team( team) ) ;
331+ format ! (
332+ "{}/{}" ,
333+ kind_to_str( team. kind) ,
334+ team. website_data. as_ref( ) . unwrap( ) . page
335+ )
336+ }
337+
338+ fn is_toplevel_team ( team : & Team ) -> bool {
339+ team. kind == TeamKind :: Team && team. subteam_of . is_none ( )
237340}
238341
239342#[ derive( Serialize ) ]
@@ -272,6 +375,49 @@ pub struct AllTeamMembers {
272375 alumni : Vec < TeamMember > ,
273376}
274377
378+ #[ derive( Serialize ) ]
379+ pub struct PersonTeam {
380+ team : Team ,
381+ toplevel_url : Option < String > ,
382+ webpage_name : String ,
383+ }
384+
385+ impl PersonTeam {
386+ fn new ( team : & Team , toplevel_url : Option < String > ) -> Self {
387+ let webpage_name = team
388+ . website_data
389+ . as_ref ( )
390+ . map ( |w| w. name . clone ( ) )
391+ . unwrap_or_else ( || {
392+ // Turn inside-rust-reviewers into Inside Rust Reviewers
393+ team. name
394+ . split ( "-" )
395+ . map ( |p| {
396+ p. chars ( )
397+ . take ( 1 )
398+ . flat_map ( |c| c. to_uppercase ( ) )
399+ . chain ( p. chars ( ) . skip ( 1 ) )
400+ . collect :: < String > ( )
401+ } )
402+ . collect :: < Vec < String > > ( )
403+ . join ( " " )
404+ } ) ;
405+ Self {
406+ team : team. clone ( ) ,
407+ toplevel_url : toplevel_url,
408+ webpage_name,
409+ }
410+ }
411+ }
412+
413+ #[ derive( Serialize ) ]
414+ pub struct PersonData {
415+ name : String ,
416+ pub github : String ,
417+ active_teams : Vec < PersonTeam > ,
418+ alumni_teams : Vec < PersonTeam > ,
419+ }
420+
275421pub fn load_rust_teams ( ) -> anyhow:: Result < RustTeams > {
276422 println ! ( "Downloading Team API data" ) ;
277423
0 commit comments