1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#![doc(alias = "community-points-channel-v1")]
//! PubSub messages for community points.
//!
//! See also [`pubsub::channel_points`]
use crate::pubsub;
use serde::{Deserialize, Serialize};

/// A user redeems an reward using channel points.
///
/// Reply is [`pubsub::channel_points::ChannelPointsChannelV1Reply`]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(into = "String", try_from = "String")]
pub struct CommunityPointsChannelV1 {
    /// The channel_id to watch. Can be fetched with the [Get Users](crate::helix::users::get_users) endpoint
    pub channel_id: u32,
}

impl_de_ser!(
    CommunityPointsChannelV1,
    "community-points-channel-v1",
    channel_id // FIXME: add trailing comma
);

impl pubsub::Topic for CommunityPointsChannelV1 {
    #[cfg(feature = "twitch_oauth2")]
    const SCOPE: &'static [twitch_oauth2::Scope] = &[twitch_oauth2::Scope::ChannelReadRedemptions];
}
#[cfg(test)]
mod tests {
    use super::super::{Response, TopicData};
    use super::*;

    #[test]
    fn channel_point_redeem() {
        let message = r##"
{
    "type": "reward-redeemed",
    "data": {
        "timestamp": "2020-10-10T19:13:30.536153182Z",
        "redemption": {
            "id": "b021f290-bedb-49c2-b90f-e6ceb1c0d4ab",
            "user": {
                "id": "27620241",
                "login": "emilgardis",
                "display_name": "emilgardis"
            },
            "channel_id": "27620241",
            "redeemed_at": "2020-10-10T19:13:30.536153182Z",
            "reward": {
                "id": "252e209d-4f16-4886-a0d1-97f458ad5698",
                "channel_id": "27620241",
                "title": "Hydration",
                "prompt": "Make Emilgardis drink water",
                "cost": 2000,
                "is_user_input_required": true,
                "is_sub_only": false,
                "image": null,
                "default_image": {
                    "url_1x": "https://static-cdn.jtvnw.net/custom-reward-images/default-1.png",
                    "url_2x": "https://static-cdn.jtvnw.net/custom-reward-images/default-2.png",
                    "url_4x": "https://static-cdn.jtvnw.net/custom-reward-images/default-4.png"
                },
                "background_color": "#81AEFF",
                "is_enabled": true,
                "is_paused": false,
                "is_in_stock": true,
                "max_per_stream": {
                    "is_enabled": false,
                    "max_per_stream": 10
                },
                "should_redemptions_skip_request_queue": false,
                "template_id": null,
                "updated_for_indicator_at": "2020-02-06T17:29:19.737311439Z",
                "max_per_user_per_stream": {
                    "is_enabled": false,
                    "max_per_user_per_stream": 0
                },
                "global_cooldown": {
                    "is_enabled": false,
                    "global_cooldown_seconds": 0
                },
                "redemptions_redeemed_current_stream": 0,
                "cooldown_expires_at": null
            },
            "user_input": "bap",
            "status": "UNFULFILLED"
        }
    }
}
"##;
        let source = format!(
            r#"{{"type": "MESSAGE","data": {{ "topic": "community-points-channel-v1.27620241", "message": {:?} }}}}"#,
            message
        );
        let actual = dbg!(Response::parse(&source).unwrap());
        assert!(matches!(
            actual,
            Response::Message {
                data: TopicData::CommunityPointsChannelV1 { .. },
            }
        ));
    }

    #[test]
    fn check_deser() {
        use std::convert::TryInto as _;
        let s = "community-points-channel-v1.1234";
        assert_eq!(
            CommunityPointsChannelV1 { channel_id: 1234 },
            s.to_string().try_into().unwrap()
        );
    }

    #[test]
    fn check_ser() {
        let s = "community-points-channel-v1.1234";
        let right: String = CommunityPointsChannelV1 { channel_id: 1234 }.into();
        assert_eq!(s.to_string(), right);
    }
}