twilight_model/application/monetization/
entitlement.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{
4    id::{
5        marker::{ApplicationMarker, EntitlementMarker, GuildMarker, SkuMarker, UserMarker},
6        Id,
7    },
8    util::Timestamp,
9};
10
11use super::entitlement_type::EntitlementType;
12
13/// Entitlements in Discord represent that a user or guild has access to a premium offering in your application.
14#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
15pub struct Entitlement {
16    /// ID of the parent application.
17    pub application_id: Id<ApplicationMarker>,
18    /// Not applicable for App Subscriptions. Subscriptions are not consumed and will be `false`
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub consumed: Option<bool>,
21    /// Entitlement was deleted.
22    pub deleted: bool,
23    /// Date at which the entitlement is no longer valid. Not present when using test entitlements.
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub ends_at: Option<Timestamp>,
26    /// ID of the guild that is granted access to the entitlement's sku.
27    #[serde(skip_serializing_if = "Option::is_none")]
28    pub guild_id: Option<Id<GuildMarker>>,
29    /// ID of the entitlement.
30    pub id: Id<EntitlementMarker>,
31    /// Type of entitlement.
32    #[serde(rename = "type")]
33    pub kind: EntitlementType,
34    /// ID of the SKU.
35    pub sku_id: Id<SkuMarker>,
36    /// Start date at which the entitlement is valid. Not present when using test entitlements.
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub starts_at: Option<Timestamp>,
39    /// ID of the user that is granted access to the entitlement's sku.
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub user_id: Option<Id<UserMarker>>,
42}
43
44#[cfg(test)]
45mod tests {
46    use std::error::Error;
47
48    use serde_test::Token;
49
50    use super::Entitlement;
51    use crate::application::monetization::entitlement_type::EntitlementType;
52    use crate::id::Id;
53    use crate::util::Timestamp;
54
55    #[test]
56    fn entitlement() -> Result<(), Box<dyn Error>> {
57        let starts_at_str = "2022-09-14T17:00:18.704163+00:00";
58        let ends_at_str = "2022-10-14T17:00:21.704163+00:00";
59        let starts_at = Timestamp::parse(starts_at_str)?;
60        let ends_at = Timestamp::parse(ends_at_str)?;
61
62        let value = Entitlement {
63            application_id: Id::new(1),
64            consumed: Some(false),
65            deleted: false,
66            ends_at: ends_at.into(),
67            guild_id: Some(Id::new(10)),
68            id: Id::new(2),
69            kind: EntitlementType::ApplicationSubscription,
70            sku_id: Id::new(3),
71            starts_at: starts_at.into(),
72            user_id: Some(Id::new(42)),
73        };
74
75        serde_test::assert_tokens(
76            &value,
77            &[
78                Token::Struct {
79                    name: "Entitlement",
80                    len: 10,
81                },
82                Token::Str("application_id"),
83                Token::NewtypeStruct { name: "Id" },
84                Token::Str("1"),
85                Token::Str("consumed"),
86                Token::Some,
87                Token::Bool(false),
88                Token::Str("deleted"),
89                Token::Bool(false),
90                Token::Str("ends_at"),
91                Token::Some,
92                Token::Str(ends_at_str),
93                Token::Str("guild_id"),
94                Token::Some,
95                Token::NewtypeStruct { name: "Id" },
96                Token::Str("10"),
97                Token::Str("id"),
98                Token::NewtypeStruct { name: "Id" },
99                Token::Str("2"),
100                Token::Str("type"),
101                Token::U8(8),
102                Token::Str("sku_id"),
103                Token::NewtypeStruct { name: "Id" },
104                Token::Str("3"),
105                Token::Str("starts_at"),
106                Token::Some,
107                Token::Str(starts_at_str),
108                Token::Str("user_id"),
109                Token::Some,
110                Token::NewtypeStruct { name: "Id" },
111                Token::Str("42"),
112                Token::StructEnd,
113            ],
114        );
115
116        Ok(())
117    }
118}