Skip to main content

twilight_model/application/monetization/
subscription.rs

1use super::SubscriptionStatus;
2use crate::{
3    id::{
4        Id,
5        marker::{EntitlementMarker, SkuMarker, SubscriptionMarker, UserMarker},
6    },
7    util::Timestamp,
8};
9use serde::{Deserialize, Serialize};
10
11/// Subscriptions in Discord represent a user making recurring payments for at
12/// least one SKU over an ongoing period. Successful payments grant the user
13/// access to entitlements associated with the SKU.
14#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
15pub struct Subscription {
16    /// When the subscription was canceled.
17    pub canceled_at: Option<Timestamp>,
18    /// ISO3166-1 alpha-2 country code of the payment source used to purchase
19    /// the subscription. Missing unless queried with a private OAuth scope.
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub country: Option<String>,
22    /// End of the current subscription period.
23    pub current_period_end: Timestamp,
24    /// Start of the current subscription period.
25    pub current_period_start: Timestamp,
26    /// List of entitlements granted for this subscription.
27    pub entitlement_ids: Vec<Id<EntitlementMarker>>,
28    /// ID of the subscription.
29    pub id: Id<SubscriptionMarker>,
30    /// List of SKUs that this user will be subscribed to at renewal.
31    pub renewal_sku_ids: Option<Vec<Id<SkuMarker>>>,
32    /// List of SKUs subscribed to.
33    pub sku_ids: Vec<Id<SkuMarker>>,
34    /// Current status of the subscription.
35    pub status: SubscriptionStatus,
36    /// ID of the user who is subscribed.
37    pub user_id: Id<UserMarker>,
38}
39
40#[cfg(test)]
41mod tests {
42    use super::{Subscription, SubscriptionStatus};
43    use crate::id::Id;
44    use crate::util::Timestamp;
45    use serde_test::Token;
46    use std::error::Error;
47
48    #[test]
49    fn entitlement() -> Result<(), Box<dyn Error>> {
50        let value = Subscription {
51            canceled_at: None,
52            country: None,
53            current_period_end: Timestamp::parse("2024-09-27T19:48:44.406602+00:00")?,
54            current_period_start: Timestamp::parse("2024-08-27T19:48:44.406602+00:00")?,
55            entitlement_ids: Vec::new(),
56            id: Id::new(1),
57            renewal_sku_ids: Some(Vec::new()),
58            sku_ids: Vec::from([Id::new(2)]),
59            status: SubscriptionStatus::Active,
60            user_id: Id::new(3),
61        };
62
63        serde_test::assert_tokens(
64            &value,
65            &[
66                Token::Struct {
67                    name: "Subscription",
68                    len: 9,
69                },
70                Token::Str("canceled_at"),
71                Token::None,
72                Token::Str("current_period_end"),
73                Token::Str("2024-09-27T19:48:44.406602+00:00"),
74                Token::Str("current_period_start"),
75                Token::Str("2024-08-27T19:48:44.406602+00:00"),
76                Token::Str("entitlement_ids"),
77                Token::Seq { len: Some(0) },
78                Token::SeqEnd,
79                Token::Str("id"),
80                Token::NewtypeStruct { name: "Id" },
81                Token::Str("1"),
82                Token::Str("renewal_sku_ids"),
83                Token::Some,
84                Token::Seq { len: Some(0) },
85                Token::SeqEnd,
86                Token::Str("sku_ids"),
87                Token::Seq { len: Some(1) },
88                Token::NewtypeStruct { name: "Id" },
89                Token::Str("2"),
90                Token::SeqEnd,
91                Token::Str("status"),
92                Token::U8(0),
93                Token::Str("user_id"),
94                Token::NewtypeStruct { name: "Id" },
95                Token::Str("3"),
96                Token::StructEnd,
97            ],
98        );
99
100        Ok(())
101    }
102}