twitch_highway 0.2.1

Twitch API
Documentation
pub mod request;
pub mod response;
pub mod types;

use request::{BlockReason, BlockSourceContext};
use response::{
    BlockUserListResponse, UpdateUsersResponse, UserActiveExtensionsResponse,
    UserExtensionsResponse, UsersInfoResponse,
};
use types::UserActiveExtensions;

use crate::{
    request::NoContent,
    types::{
        constants::{BROADCASTER_ID, EXTENSIONS, ID, USER_ID},
        BroadcasterId, Id, PaginationQuery, UserId,
    },
};

const USERS: &str = "users";
const BLOCKS: &str = "blocks";
const LOGIN: &str = "login";

endpoints! {
    UserAPI {
        /// <https://dev.twitch.tv/docs/api/reference/#get-users>
        fn get_users(
            &self,
            ids: Option<&[Id]>,
            logins: Option<&[&str]>,
        ) -> UsersInfoResponse {
            endpoint_type: GetUsers,
            method: GET,
            path: [USERS],
            query_params: {
                opt_extend(ids.map(|ids| ids.iter().map(|id| (ID, id)))),
                opt_extend(logins.map(|lg| lg.iter().map(|l| (LOGIN, l) )))
            }
        }

        /// <https://dev.twitch.tv/docs/api/reference/#update-user>
        fn update_user(&self, description: Option<&str>) -> UpdateUsersResponse {
            endpoint_type: UpdateUser,
            method: PUT,
            path: [USERS],
            query_params: {
                opt("description", description)
            }
        }

        /// <https://dev.twitch.tv/docs/api/reference/#get-user-block-list>
        fn get_user_block_list(
            &self,
            broadcaster_id: &BroadcasterId,
            pagination: Option<PaginationQuery>,
        ) -> BlockUserListResponse {
            endpoint_type: GetUserBlockList,
            method: GET,
            path: [USERS, BLOCKS],
            query_params: {
                query(BROADCASTER_ID, broadcaster_id),
                pagination(pagination)
            }
        }

        /// <https://dev.twitch.tv/docs/api/reference/#block-user>
        fn block_user(
            &self,
            target_user_id: &UserId,
            source_context: Option<BlockSourceContext>,
            reason: Option<BlockReason>,
        ) -> NoContent {
            endpoint_type: BlockUser,
            method: PUT,
            path: [USERS, BLOCKS],
            query_params: {
                query("target_user_id", target_user_id),
                opt("source_context", source_context),
                opt("reason", reason)
            }
        }

        /// <https://dev.twitch.tv/docs/api/reference/#unblock-user>
        fn unblock_user(&self, target_user_id: &UserId) -> NoContent {
            endpoint_type: UnblockUser,
            method: DELETE,
            path: [USERS, BLOCKS],
            query_params: {
                query("target_user_id", target_user_id)
            }
        }

        /// <https://dev.twitch.tv/docs/api/reference/#get-user-extensions>
        fn get_user_extensions(&self) -> UserExtensionsResponse {
            endpoint_type: GetUserExtensions,
            method: GET,
            path: [USERS, EXTENSIONS, "list"]
        }

        /// <https://dev.twitch.tv/docs/api/reference/#get-user-active-extensions>
        fn get_user_active_extensions(
            &self,
            user_id: Option<&UserId>,
        ) -> UserActiveExtensionsResponse {
            endpoint_type: GetUserActiveExtensions,
            method: GET,
            path: [USERS, EXTENSIONS],
            query_params: {
                opt(USER_ID, user_id)
            }
        }

        /// <https://dev.twitch.tv/docs/api/reference/#update-user-extensions>
        fn update_user_extensions(
            &self,
            data: UserActiveExtensions,
        ) -> UserActiveExtensionsResponse {
            endpoint_type: UpdateUserExtensions,
            method: PUT,
            path: [USERS, EXTENSIONS],
            headers: [json],
            body: data.into_json()
        }
    }
}

#[cfg(test)]
mod tests {
    use std::collections::HashMap;

    use crate::{
        types::{BroadcasterId, Id, UserId},
        users::{
            types::{Component, Overlay, Panel, UserActiveExtensions},
            UserAPI,
        },
    };
    api_test!(get_users, [Some(&[Id::from("141981764")]), None]);
    api_test!(update_user, [Some("BaldAngel")]);
    api_test!(
        get_user_block_list,
        [&BroadcasterId::from("141981764"), None]
    );
    api_test!(block_user, [&UserId::from("198704263"), None, None]);
    api_test!(unblock_user, [&UserId::from("198704263")]);
    api_test!(get_user_extensions, []);
    api_test!(get_user_active_extensions, [None]);
    api_test!(
        update_user_extensions,
        [{
            let mut panels = HashMap::new();
            panels.insert(
                "1".to_string(),
                Panel::new(true)
                    .id(Id::from("rh6jq1q334hqc2rr1qlzqbvwlfl3x0"))
                    .version("1.1.8".to_string()),
            );

            panels.insert(
                "2".to_string(),
                Panel::new(true)
                    .id(Id::from("wi08ebtatdc7oj83wtl9uxwz807l8b"))
                    .version("1.1.8"),
            );

            panels.insert(
                "2".to_string(),
                Panel::new(true)
                    .id(Id::from("naty2zwfp7vecaivuve8ef1hohh6bo"))
                    .version("1.1.8"),
            );

            let mut overlays = HashMap::new();
            overlays.insert(
                "1".to_string(),
                Overlay::new(true)
                    .id(Id::from("zfh2irvx2jb4s60f02jq0ajm8vwgka"))
                    .version("1.0.19"),
            );

            let mut components = HashMap::new();
            components.insert(
                "1".to_string(),
                Component::new(true)
                    .id(Id::from("lqnf3zxk0rv0g7gq92mtmnirjz2cjj"))
                    .version("0.0.1")
                    .name("Dev Experience Test")
                    .x(0)
                    .y(0),
            );

            components.insert("2".to_string(), Component::new(false));

            UserActiveExtensions::new(panels, overlays, components)
        }]
    );
}