twitch_api/helix/endpoints/subscriptions/
get_broadcaster_subscriptions.rs1use super::*;
39use helix::RequestGet;
40
41#[derive(PartialEq, Eq, Deserialize, Serialize, Clone, Debug)]
45#[cfg_attr(feature = "typed-builder", derive(typed_builder::TypedBuilder))]
46#[must_use]
47#[non_exhaustive]
48pub struct GetBroadcasterSubscriptionsRequest<'a> {
49 #[cfg_attr(feature = "typed-builder", builder(setter(into)))]
51 #[cfg_attr(feature = "deser_borrow", serde(borrow = "'a"))]
52 pub broadcaster_id: Cow<'a, types::UserIdRef>,
53 #[cfg_attr(feature = "typed-builder", builder(default))]
55 #[cfg_attr(feature = "deser_borrow", serde(borrow = "'a"))]
56 #[cfg_attr(not(feature = "deser_borrow"), serde(bound(deserialize = "'de: 'a")))]
58 pub user_id: types::Collection<'a, types::UserId>,
59 #[cfg_attr(feature = "typed-builder", builder(default))]
61 #[cfg_attr(feature = "deser_borrow", serde(borrow = "'a"))]
62 pub after: Option<Cow<'a, helix::CursorRef>>,
63 #[cfg_attr(feature = "typed-builder", builder(setter(into), default))]
65 pub first: Option<usize>,
66}
67
68impl<'a> GetBroadcasterSubscriptionsRequest<'a> {
69 pub fn broadcaster_id(broadcaster_id: impl types::IntoCow<'a, types::UserIdRef> + 'a) -> Self {
71 Self {
72 broadcaster_id: broadcaster_id.into_cow(),
73 user_id: types::Collection::default(),
74 after: Default::default(),
75 first: Default::default(),
76 }
77 }
78
79 pub fn subscriber(mut self, user_ids: impl Into<types::Collection<'a, types::UserId>>) -> Self {
81 self.user_id = user_ids.into();
82 self
83 }
84
85 pub const fn first(mut self, first: usize) -> Self {
87 self.first = Some(first);
88 self
89 }
90}
91
92#[derive(PartialEq, Eq, Deserialize, Serialize, Debug, Clone)]
96#[cfg_attr(feature = "deny_unknown_fields", serde(deny_unknown_fields))]
97#[non_exhaustive]
98pub struct BroadcasterSubscription {
99 pub broadcaster_id: types::UserId,
101 pub broadcaster_login: types::UserName,
103 pub broadcaster_name: types::DisplayName,
105 #[serde(
107 default,
108 deserialize_with = "crate::deserialize_none_from_empty_string"
109 )]
110 pub gifter_id: Option<types::UserId>,
111 #[serde(
113 default,
114 deserialize_with = "crate::deserialize_none_from_empty_string"
115 )]
116 pub gifter_login: Option<types::UserName>,
117 #[serde(
119 default,
120 deserialize_with = "crate::deserialize_none_from_empty_string"
121 )]
122 pub gifter_name: Option<types::DisplayName>,
123 pub is_gift: bool,
125 pub tier: types::SubscriptionTier,
127 pub plan_name: String,
129 pub user_id: types::UserId,
131 pub user_login: types::UserName,
133 pub user_name: types::DisplayName,
135}
136
137impl Request for GetBroadcasterSubscriptionsRequest<'_> {
138 type Response = Vec<BroadcasterSubscription>;
139
140 const PATH: &'static str = "subscriptions";
141 #[cfg(feature = "twitch_oauth2")]
142 const SCOPE: twitch_oauth2::Validator =
143 twitch_oauth2::validator![twitch_oauth2::Scope::ChannelReadSubscriptions];
144}
145
146impl RequestGet for GetBroadcasterSubscriptionsRequest<'_> {}
147
148impl helix::Paginated for GetBroadcasterSubscriptionsRequest<'_> {
149 fn set_pagination(&mut self, cursor: Option<helix::Cursor>) {
150 self.after = cursor.map(|c| c.into_cow())
151 }
152}
153
154impl helix::Response<GetBroadcasterSubscriptionsRequest<'_>, Vec<BroadcasterSubscription>> {
155 pub fn points(&self) -> Result<i64, BroadcasterSubscriptionPointsError> {
157 let points = self.get_other("points")?;
158 if let Some(points) = points {
159 Ok(points)
160 } else {
161 Err(BroadcasterSubscriptionPointsError::PointsNotFound)
162 }
163 }
164}
165
166#[derive(Debug, thiserror::Error)]
168#[non_exhaustive]
169pub enum BroadcasterSubscriptionPointsError {
170 #[error(transparent)]
172 DeserError(#[from] serde_json::Error),
173 #[error("`points` not found in the response")]
175 PointsNotFound,
176}
177
178#[cfg(test)]
179#[test]
180fn test_request() {
181 use helix::*;
182 let req = GetBroadcasterSubscriptionsRequest::broadcaster_id("123");
183
184 let data = br#"
186 {
187 "data": [
188 {
189 "broadcaster_id": "141981764",
190 "broadcaster_login": "twitchdev",
191 "broadcaster_name": "TwitchDev",
192 "gifter_id": "12826",
193 "gifter_login": "twitch",
194 "gifter_name": "Twitch",
195 "is_gift": true,
196 "tier": "1000",
197 "plan_name": "Channel Subscription (twitchdev)",
198 "user_id": "527115020",
199 "user_name": "twitchgaming",
200 "user_login": "twitchgaming"
201 }
202 ],
203 "pagination": {
204 "cursor": "xxxx"
205 },
206 "total": 13,
207 "points": 13
208 }
209"#
210 .to_vec();
211
212 let http_response = http::Response::builder().body(data).unwrap();
213
214 let uri = req.get_uri().unwrap();
215 assert_eq!(
216 uri.to_string(),
217 "https://api.twitch.tv/helix/subscriptions?broadcaster_id=123"
218 );
219
220 let resp =
221 dbg!(
222 GetBroadcasterSubscriptionsRequest::parse_response(Some(req), &uri, http_response)
223 .unwrap()
224 );
225 assert_eq!(resp.total, Some(13));
226 assert_eq!(resp.points().unwrap(), 13);
227}