lichess_api/model/users/
activity.rs

1use crate::model::{Color, Request, VariantKey};
2use serde::{Deserialize, Serialize};
3use serde_with::skip_serializing_none;
4use std::collections::HashMap;
5
6#[derive(Default, Clone, Debug, Deserialize, Serialize)]
7pub struct GetQuery;
8
9pub type GetRequest = Request<GetQuery>;
10
11impl GetRequest {
12    pub fn new(username: &str) -> Self {
13        Self::get(format!("/api/user/{username}/activity"), None, None)
14    }
15}
16
17// Main UserActivity struct matching OpenAPI spec
18#[skip_serializing_none]
19#[derive(Clone, Debug, Deserialize, Serialize)]
20#[serde(rename_all = "camelCase")]
21pub struct UserActivity {
22    pub interval: ActivityInterval,
23    pub games: Option<HashMap<String, UserActivityScore>>,
24    pub puzzles: Option<PuzzleActivity>,
25    pub storm: Option<PuzzleModePerf>,
26    pub racer: Option<PuzzleModePerf>,
27    pub streak: Option<PuzzleModePerf>,
28    pub tournaments: Option<TournamentActivity>,
29    pub practice: Option<Vec<PracticeActivity>>,
30    pub simuls: Option<Vec<String>>,
31    pub correspondence_moves: Option<CorrespondenceMoves>,
32    pub correspondence_ends: Option<CorrespondenceEnds>,
33    pub follows: Option<FollowActivity>,
34    pub studies: Option<serde_json::Value>, // OpenAPI shows empty object
35    pub teams: Option<Vec<TeamActivity>>,
36    pub posts: Option<Vec<PostActivity>>,
37    pub patron: Option<PatronActivity>,
38    pub stream: Option<bool>,
39}
40
41#[derive(Clone, Debug, Deserialize, Serialize)]
42pub struct ActivityInterval {
43    pub start: u64,
44    pub end: u64,
45}
46
47#[derive(Clone, Debug, Deserialize, Serialize)]
48pub struct UserActivityScore {
49    pub win: u32,
50    pub loss: u32,
51    pub draw: u32,
52    pub rp: RatingProgress,
53}
54
55#[derive(Clone, Debug, Deserialize, Serialize)]
56pub struct RatingProgress {
57    pub before: u32,
58    pub after: u32,
59}
60
61#[derive(Clone, Debug, Deserialize, Serialize)]
62pub struct PuzzleActivity {
63    pub score: UserActivityScore,
64}
65
66#[derive(Clone, Debug, Deserialize, Serialize)]
67pub struct PuzzleModePerf {
68    pub runs: u32,
69    pub score: u32,
70}
71
72#[skip_serializing_none]
73#[derive(Clone, Debug, Deserialize, Serialize)]
74#[serde(rename_all = "camelCase")]
75pub struct TournamentActivity {
76    pub nb: u32,
77    pub best: Option<Vec<TournamentResult>>,
78}
79
80#[derive(Clone, Debug, Deserialize, Serialize)]
81#[serde(rename_all = "camelCase")]
82pub struct TournamentResult {
83    pub tournament: TournamentInfo,
84    pub nb_games: u32,
85    pub score: u32,
86    pub rank: u32,
87    pub rank_percent: u32,
88}
89
90#[derive(Clone, Debug, Deserialize, Serialize)]
91pub struct TournamentInfo {
92    pub id: String,
93    pub name: String,
94}
95
96#[derive(Clone, Debug, Deserialize, Serialize)]
97#[serde(rename_all = "camelCase")]
98pub struct PracticeActivity {
99    pub url: String,
100    pub name: String,
101    pub nb_positions: u32,
102}
103
104#[derive(Clone, Debug, Deserialize, Serialize)]
105pub struct CorrespondenceMoves {
106    pub nb: u32,
107    pub games: Vec<UserActivityCorrespondenceGame>,
108}
109
110#[derive(Clone, Debug, Deserialize, Serialize)]
111pub struct CorrespondenceEnds {
112    pub score: UserActivityScore,
113    pub games: Vec<UserActivityCorrespondenceGame>,
114}
115
116#[derive(Clone, Debug, Deserialize, Serialize)]
117pub struct UserActivityCorrespondenceGame {
118    pub id: String,
119    pub color: Color,
120    pub url: String,
121    pub variant: VariantKey,
122    pub speed: String, // Always "correspondence"
123    pub perf: String,  // Always "correspondence"
124    pub rated: bool,
125    pub opponent: CorrespondenceOpponent,
126}
127
128#[derive(Clone, Debug, Deserialize, Serialize)]
129pub struct CorrespondenceOpponent {
130    pub user: String,
131    pub rating: u32,
132}
133
134#[skip_serializing_none]
135#[derive(Clone, Debug, Deserialize, Serialize)]
136pub struct FollowActivity {
137    #[serde(rename = "in")]
138    pub incoming: Option<UserActivityFollowList>,
139    pub out: Option<UserActivityFollowList>,
140}
141
142#[derive(Clone, Debug, Deserialize, Serialize)]
143pub struct UserActivityFollowList {
144    pub ids: Vec<String>,
145    #[serde(skip_serializing_if = "Option::is_none")]
146    pub nb: Option<u32>,
147}
148
149#[skip_serializing_none]
150#[derive(Clone, Debug, Deserialize, Serialize)]
151pub struct TeamActivity {
152    pub url: String,
153    pub name: String,
154    pub flair: Option<String>,
155}
156
157#[derive(Clone, Debug, Deserialize, Serialize)]
158#[serde(rename_all = "camelCase")]
159pub struct PostActivity {
160    pub topic_url: String,
161    pub topic_name: String,
162    pub posts: Vec<PostInfo>,
163}
164
165#[derive(Clone, Debug, Deserialize, Serialize)]
166pub struct PostInfo {
167    pub url: String,
168    pub text: String,
169}
170
171#[derive(Clone, Debug, Deserialize, Serialize)]
172pub struct PatronActivity {
173    pub months: u32,
174}