solutions.rs
1 use std::{cmp::Reverse, collections::HashMap, fmt::Write}; 2 3 use matrix_sdk::{Room, ruma::events::room::message::OriginalRoomMessageEvent}; 4 5 use crate::{ 6 Context, 7 aoc::{day::AocDay, models::PrivateLeaderboardMember}, 8 matrix::{ 9 commands::CommandResult, 10 utils::{RoomExt, html_message}, 11 }, 12 }; 13 14 pub async fn invoke( 15 event: &OriginalRoomMessageEvent, 16 room: &Room, 17 context: &Context, 18 ) -> CommandResult<()> { 19 let aoc_users = context 20 .aoc_client 21 .get_private_leaderboard(AocDay::most_recent().year) 22 .await? 23 .0 24 .members 25 .into_values() 26 .map(|u| (u.id, u)) 27 .collect::<HashMap<_, _>>(); 28 29 let mut solutions = String::from( 30 r#" 31 <h3>Advent of Code Solution Repositories</h3> 32 <table> 33 <tr> <th>AoC Name</th> <th>Matrix User</th> <th>Repository</th> </tr> 34 "#, 35 ); 36 37 let mut rows = Vec::new(); 38 39 for user in &context.config.users { 40 let Some(repo) = &user.repo else { continue }; 41 42 let aoc_user = user.aoc.and_then(|id| aoc_users.get(&id)); 43 44 let name = aoc_user.map(|u| u.display_name()).unwrap_or_default(); 45 46 let matrix_name = user 47 .matrix 48 .as_ref() 49 .map(|m| m.matrix_to_uri().to_string()) 50 .unwrap_or_default(); 51 52 let repo_title = context 53 .config 54 .aoc 55 .repo_rules 56 .match_and_replace(repo) 57 .map(|m| m.replacement); 58 59 rows.push((aoc_user, name, matrix_name, repo, repo_title)); 60 } 61 62 rows.sort_unstable_by(|a, b| { 63 fn key<'a>( 64 aoc_user: Option<&'a PrivateLeaderboardMember>, 65 name: &'a str, 66 ) -> impl Ord + use<'a> { 67 (Reverse(aoc_user.map(Reverse)), name) 68 } 69 key(a.0, &a.1).cmp(&key(b.0, &b.1)) 70 }); 71 72 for (_, name, matrix_name, repo, repo_title) in rows { 73 let repo_title = repo_title.as_deref().unwrap_or(repo); 74 let link_prefix = &context.config.matrix.link_prefix; 75 write!( 76 &mut solutions, 77 r#" 78 <tr> 79 <td>{name}</td> 80 <td>{matrix_name}</td> 81 <td><a href="{link_prefix}{repo}">{repo_title}</a></td> 82 </tr> 83 "# 84 ) 85 .unwrap(); 86 } 87 88 solutions.push_str("</table>"); 89 90 room.reply_to(event, html_message(solutions)).await?; 91 92 Ok(()) 93 }