Skip to main content

twilight_http/request/application/monetization/
get_entitlements.rs

1use std::future::IntoFuture;
2
3use twilight_model::{
4    application::monetization::Entitlement,
5    id::{
6        Id,
7        marker::{ApplicationMarker, EntitlementMarker, GuildMarker, SkuMarker, UserMarker},
8    },
9};
10
11use crate::{
12    Client, Error, Response,
13    request::{Request, TryIntoRequest},
14    response::{ResponseFuture, marker::ListBody},
15    routing::Route,
16};
17
18use twilight_validate::request::{
19    ValidationError, get_entitlements_limit as validate_get_entitlements_limit,
20};
21
22struct GetEntitlementsFields<'a> {
23    after: Option<Id<EntitlementMarker>>,
24    before: Option<Id<EntitlementMarker>>,
25    exclude_deleted: Option<bool>,
26    exclude_ended: Option<bool>,
27    guild_id: Option<Id<GuildMarker>>,
28    limit: Option<u8>,
29    sku_ids: &'a [Id<SkuMarker>],
30    user_id: Option<Id<UserMarker>>,
31}
32
33/// Get all entitlements for a given app, active and expired.
34#[must_use = "requests must be configured and executed"]
35pub struct GetEntitlements<'a> {
36    application_id: Id<ApplicationMarker>,
37    fields: GetEntitlementsFields<'a>,
38    http: &'a Client,
39}
40
41impl<'a> GetEntitlements<'a> {
42    pub(crate) const fn new(http: &'a Client, application_id: Id<ApplicationMarker>) -> Self {
43        Self {
44            application_id,
45            fields: GetEntitlementsFields {
46                after: None,
47                before: None,
48                exclude_deleted: None,
49                exclude_ended: None,
50                guild_id: None,
51                limit: None,
52                sku_ids: &[],
53                user_id: None,
54            },
55            http,
56        }
57    }
58
59    /// Retrieve entitlements after this time.
60    pub const fn after(mut self, after: Id<EntitlementMarker>) -> Self {
61        self.fields.after = Some(after);
62
63        self
64    }
65
66    /// Retrieve entitlements before this time.
67    pub const fn before(mut self, before: Id<EntitlementMarker>) -> Self {
68        self.fields.before = Some(before);
69
70        self
71    }
72
73    /// Whether to exclude deleted entitlements.
74    ///
75    /// Discord's API defaults to true.
76    pub const fn exclude_deleted(mut self, exclude_ended: bool) -> Self {
77        self.fields.exclude_ended = Some(exclude_ended);
78
79        self
80    }
81
82    /// Whether to exclude ended entitlements.
83    pub const fn exclude_ended(mut self, exclude_ended: bool) -> Self {
84        self.fields.exclude_ended = Some(exclude_ended);
85
86        self
87    }
88
89    /// Guild ID to look up entitlements for.
90    pub const fn guild_id(mut self, guild_id: Id<GuildMarker>) -> Self {
91        self.fields.guild_id = Some(guild_id);
92
93        self
94    }
95
96    /// Number of entitlements to return. Set to 100 if unspecified.
97    ///
98    /// The minimum is 1 and the maximum is 100.
99    ///
100    /// # Errors
101    ///
102    /// Returns a [`GetEntitlementsError`] error type if the amount
103    /// is less than 1 or greater than 100.
104    ///
105    /// [`GetEntitlementsError`]: twilight_validate::request::ValidationErrorType::GetEntitlements
106    pub fn limit(mut self, limit: u8) -> Result<Self, ValidationError> {
107        validate_get_entitlements_limit(limit)?;
108
109        self.fields.limit = Some(limit);
110
111        Ok(self)
112    }
113
114    /// List of SKU IDs to check entitlements for.
115    pub const fn sku_ids(mut self, sku_ids: &'a [Id<SkuMarker>]) -> Self {
116        self.fields.sku_ids = sku_ids;
117
118        self
119    }
120
121    /// User ID to look up entitlements for.
122    pub const fn user_id(mut self, user_id: Id<UserMarker>) -> Self {
123        self.fields.user_id = Some(user_id);
124
125        self
126    }
127}
128
129impl IntoFuture for GetEntitlements<'_> {
130    type Output = Result<Response<ListBody<Entitlement>>, Error>;
131
132    type IntoFuture = ResponseFuture<ListBody<Entitlement>>;
133
134    fn into_future(self) -> Self::IntoFuture {
135        let http = self.http;
136
137        match self.try_into_request() {
138            Ok(request) => http.request(request),
139            Err(source) => ResponseFuture::error(source),
140        }
141    }
142}
143
144impl TryIntoRequest for GetEntitlements<'_> {
145    fn try_into_request(self) -> Result<Request, Error> {
146        Ok(Request::from_route(&Route::GetEntitlements {
147            after: self.fields.after.map(Id::get),
148            application_id: self.application_id.get(),
149            before: self.fields.before.map(Id::get),
150            exclude_deleted: self.fields.exclude_deleted,
151            exclude_ended: self.fields.exclude_ended,
152            guild_id: self.fields.guild_id.map(Id::get),
153            limit: self.fields.limit,
154            sku_ids: self.fields.sku_ids,
155            user_id: self.fields.user_id.map(Id::get),
156        }))
157    }
158}