Two teams try and fill in any horizontal, vertical, or diagonal line on a bingo board by playing maps on osu!
osu.bingo
osu
1use chrono::{DateTime, Utc};
2use juniper::{FieldError, FieldResult, graphql_object};
3use serde::{Deserialize, Serialize};
4
5use crate::{
6 database::DataContext,
7 schema::{Chat, Float, GameUser, Long, Template},
8};
9
10#[derive(sqlx::FromRow, Deserialize, Serialize)]
11pub struct User {
12 id: i32,
13
14 username: String,
15 country_code: String,
16 country_name: String,
17
18 cover_url: String,
19 avatar_url: String,
20
21 pp: f32,
22 global_rank: Option<i32>,
23 country_rank: Option<i32>,
24
25 total_score: Option<i64>,
26 ranked_score: Option<i64>,
27 hit_accuracy: Option<f32>,
28 play_count: Option<i32>,
29 level: Option<i32>,
30 level_progress: Option<i32>,
31
32 last_refreshed: DateTime<Utc>,
33}
34
35#[graphql_object(description = "Represents an osu! user (and a bingo user)", Context = DataContext)]
36impl User {
37 pub fn id(&self) -> i32 {
38 self.id
39 }
40
41 /// Matches the user's osu! username
42 pub fn username(&self) -> &str {
43 &self.username
44 }
45
46 /// The country they are from (US, GE, CA)
47 pub fn country_code(&self) -> &str {
48 &self.country_code
49 }
50
51 /// The country they are from (United States, Germany, Canada)
52 pub fn country_name(&self) -> &str {
53 &self.country_name
54 }
55
56 /// The url for their profile banner
57 pub fn cover_url(&self) -> &str {
58 &self.cover_url
59 }
60
61 /// The url for their profile picture
62 pub fn avatar_url(&self) -> &str {
63 &self.avatar_url
64 }
65
66 pub fn pp(&self) -> Float {
67 self.pp.into()
68 }
69
70 pub fn global_rank(&self) -> Option<i32> {
71 self.global_rank
72 }
73
74 pub fn country_rank(&self) -> Option<i32> {
75 self.country_rank
76 }
77
78 pub fn total_score(&self) -> Option<Long> {
79 self.total_score.map(|x| x.into())
80 }
81
82 pub fn ranked_score(&self) -> Option<Long> {
83 self.ranked_score.map(|x| x.into())
84 }
85
86 pub fn hit_accuracy(&self) -> Option<Float> {
87 self.hit_accuracy.map(|x| x.into())
88 }
89
90 pub fn play_count(&self) -> Option<i32> {
91 self.play_count
92 }
93
94 pub fn level(&self) -> Option<i32> {
95 self.level
96 }
97
98 pub fn level_progress(&self) -> Option<i32> {
99 self.level_progress
100 }
101
102 pub fn last_refreshed(&self) -> &DateTime<Utc> {
103 &self.last_refreshed
104 }
105
106 pub async fn in_games(&self, context: &DataContext) -> FieldResult<Vec<GameUser>> {
107 context
108 .acquire()
109 .await
110 .get_user_gameusers(self.id)
111 .await
112 .map_err(FieldError::from)
113 }
114
115 pub async fn chats(&self, context: &DataContext) -> FieldResult<Vec<Chat>> {
116 context
117 .acquire()
118 .await
119 .get_user_chats(self.id)
120 .await
121 .map_err(FieldError::from)
122 }
123
124 pub async fn templates(&self, context: &DataContext) -> FieldResult<Vec<Template>> {
125 context
126 .acquire()
127 .await
128 .get_user_templates(self.id)
129 .await
130 .map_err(FieldError::from)
131 }
132}