Skip to main content

steam_user/types/
notifications.rs

1/// Notification counts from Steam.
2#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
3pub struct Notifications {
4    /// Trade offer notifications.
5    pub trades: u32,
6    /// Game turns (for turn-based games).
7    pub game_turns: u32,
8    /// Moderator messages.
9    pub moderator_messages: u32,
10    /// Profile comments.
11    pub comments: u32,
12    /// New items.
13    pub items: u32,
14    /// Group/friend invites.
15    pub invites: u32,
16    /// Gift notifications.
17    pub gifts: u32,
18    /// Chat messages.
19    pub chat: u32,
20    /// Help request replies.
21    pub help_request_replies: u32,
22    /// Account alerts.
23    pub account_alerts: u32,
24}
25
26/// Raw shape returned by Steam's `GetNotificationCounts` endpoint.
27///
28/// Steam sends a JSON object with **string keys** like `"1"`, `"2"`, … `"11"`
29/// mapping to integer counts. This struct mirrors that wire format with
30/// `#[serde(rename = "...")]` and feeds [`NotificationCountsEnvelope`] which
31/// is then narrowed into the public [`Notifications`] type.
32///
33/// Missing keys default to `0`. Counts are stored as `u64` so that values
34/// exceeding `u32::MAX` (extremely unlikely but technically possible on the
35/// wire) can be detected and saturated, rather than silently truncated.
36#[derive(Debug, Clone, Default, serde::Deserialize)]
37#[serde(default)]
38pub struct RawNotificationCounts {
39    #[serde(rename = "1")]
40    pub trades: u64,
41    #[serde(rename = "2")]
42    pub game_turns: u64,
43    #[serde(rename = "3")]
44    pub moderator_messages: u64,
45    #[serde(rename = "4")]
46    pub comments: u64,
47    #[serde(rename = "5")]
48    pub items: u64,
49    #[serde(rename = "6")]
50    pub invites: u64,
51    #[serde(rename = "8")]
52    pub gifts: u64,
53    #[serde(rename = "9")]
54    pub chat: u64,
55    #[serde(rename = "10")]
56    pub help_request_replies: u64,
57    #[serde(rename = "11")]
58    pub account_alerts: u64,
59}
60
61impl From<RawNotificationCounts> for Notifications {
62    fn from(raw: RawNotificationCounts) -> Self {
63        // Saturate at u32::MAX rather than wrapping/truncating (no `as` casts).
64        let narrow = |v: u64| u32::try_from(v).unwrap_or(u32::MAX);
65        Self {
66            trades: narrow(raw.trades),
67            game_turns: narrow(raw.game_turns),
68            moderator_messages: narrow(raw.moderator_messages),
69            comments: narrow(raw.comments),
70            items: narrow(raw.items),
71            invites: narrow(raw.invites),
72            gifts: narrow(raw.gifts),
73            chat: narrow(raw.chat),
74            help_request_replies: narrow(raw.help_request_replies),
75            account_alerts: narrow(raw.account_alerts),
76        }
77    }
78}
79
80/// Envelope wrapping the `notifications` object inside the
81/// `GetNotificationCounts` response.
82#[derive(Debug, Clone, Default, serde::Deserialize)]
83#[serde(default)]
84pub struct NotificationCountsEnvelope {
85    pub notifications: RawNotificationCounts,
86}