@@ -104,7 +104,8 @@ pub async fn gen_card(
104104 rank : i64 ,
105105) -> Result < Attachment , Error > {
106106 let customizations_future = get_customizations_fields ( state. clone ( ) , user. id , guild_id) ;
107- let avatar_future = get_avatar ( state. clone ( ) , user. id , user. avatar ) ;
107+ let avatar_ref = AvatarReference :: new ( user. id , user. avatar , guild_id, user. local_avatar ) ;
108+ let avatar_future = get_avatar ( & state. http , avatar_ref) ;
108109 let ( customizations, avatar) = try_join ! ( customizations_future, avatar_future) ?;
109110 #[ allow( clippy:: cast_sign_loss, clippy:: cast_possible_truncation) ]
110111 let percentage = ( level_info. percentage ( ) * 100.0 ) . round ( ) as u64 ;
@@ -184,22 +185,51 @@ fn color_or_default(color: Option<&str>, default: Color) -> Result<Color, Error>
184185 }
185186}
186187
187- async fn get_avatar (
188- state : SlashState ,
189- user_id : Id < UserMarker > ,
190- avatar_hash : Option < ImageHash > ,
191- ) -> Result < String , Error > {
192- let url = avatar_hash. map_or_else (
193- || {
194- format ! (
188+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
189+ struct AvatarReference {
190+ id : Id < UserMarker > ,
191+ kind : Option < AvatarReferenceKind > ,
192+ }
193+
194+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
195+ enum AvatarReferenceKind {
196+ Guild ( Id < GuildMarker > , ImageHash ) ,
197+ User ( ImageHash ) ,
198+ }
199+
200+ impl AvatarReference {
201+ pub fn new (
202+ id : Id < UserMarker > ,
203+ user_hash : Option < ImageHash > ,
204+ guild_id : Option < Id < GuildMarker > > ,
205+ guild_hash : Option < ImageHash > ,
206+ ) -> Self {
207+ let kind = guild_hash
208+ . and_then ( |hash| Some ( AvatarReferenceKind :: Guild ( guild_id?, hash) ) )
209+ . or_else ( || user_hash. map ( AvatarReferenceKind :: User ) ) ;
210+ Self { id, kind }
211+ }
212+
213+ pub fn to_url ( self ) -> String {
214+ let user_id = self . id ;
215+ match self . kind {
216+ Some ( AvatarReferenceKind :: Guild ( guild_id, avatar_hash) ) =>format ! (
217+ "https://cdn.discordapp.com/guilds/{guild_id}/users/{user_id}/avatars/{avatar_hash}.png" ,
218+ ) ,
219+ Some ( AvatarReferenceKind :: User ( avatar_hash) ) => format ! ( "https://cdn.discordapp.com/avatars/{user_id}/{avatar_hash}.png" , ) ,
220+ None => format ! (
195221 "https://cdn.discordapp.com/embed/avatars/{}.png" ,
196222 ( user_id. get( ) >> 22 ) % 6
197223 )
198- } ,
199- |hash| format ! ( "https://cdn.discordapp.com/avatars/{user_id}/{hash}.png" , ) ,
200- ) ;
224+ }
225+ }
226+ }
227+
228+ #[ tracing:: instrument( skip( client) ) ]
229+ async fn get_avatar ( client : & reqwest:: Client , avatar : AvatarReference ) -> Result < String , Error > {
230+ let url = avatar. to_url ( ) ;
201231 debug ! ( url, "Downloading avatar" ) ;
202- let png = state . http . get ( url) . send ( ) . await ?. bytes ( ) . await ?;
232+ let png = client . get ( url) . send ( ) . await ?. bytes ( ) . await ?;
203233 debug ! ( "Encoding avatar" ) ;
204234 let data = "data:image/png;base64," . to_string ( ) + & BASE64_ENGINE . encode ( png) ;
205235 debug ! ( "Encoded avatar" ) ;
0 commit comments