roblox-api 0.1.4

Roblox web api bindings
Documentation
use serde::{Deserialize, Serialize};

use crate::{DateTime, Error, Paging, client::Client};

pub const URL: &str = "https://groups.roblox.com/v1";

#[derive(Clone, Debug, Deserialize)]
pub struct GroupUser {
    #[serde(rename = "userId")]
    pub id: u64,
    #[serde(rename = "username")]
    pub name: String,
    #[serde(rename = "displayName")]
    pub display_name: String,
    #[serde(rename = "hasVerifiedBadge")]
    pub is_verified: bool,
}

#[derive(Clone, Debug, Deserialize)]
pub struct GroupRole {
    pub id: u64,
    pub name: String,
    pub rank: u8,
}

#[derive(Clone, Debug, Deserialize)]
pub struct GroupShout {
    pub body: String,
    pub poster: GroupUser,
    pub created: DateTime,
    pub updated: DateTime,
}

#[derive(Clone, Debug, Deserialize)]
pub struct GroupInformation {
    pub id: u64,
    pub name: String,
    pub description: String,

    pub owner: Option<GroupUser>,
    pub shout: Option<GroupShout>,

    #[serde(rename = "memberCount")]
    pub member_count: u64,
    #[serde(rename = "isBuildersClubOnly")]
    pub premium_only: bool,
    #[serde(rename = "publicEntryAllowed")]
    pub is_public: bool,
    #[serde(rename = "hasVerifiedBadge")]
    pub is_verified: bool,
}

pub struct GroupUsers {
    pub users: Vec<(GroupUser, GroupRole)>,
    pub next_cursor: Option<String>,
    pub previous_cursor: Option<String>,
}

pub async fn information(client: &mut Client, id: u64) -> Result<GroupInformation, Error> {
    let result = client
        .requestor
        .client
        .get(format!("{URL}/groups/{id}"))
        .headers(client.requestor.default_headers.clone())
        .send()
        .await;

    let response = client.validate_response(result).await?;
    client
        .requestor
        .parse_json::<GroupInformation>(response)
        .await
}

pub async fn roles(client: &mut Client, id: u64) -> Result<Vec<GroupRole>, Error> {
    let result = client
        .requestor
        .client
        .get(format!("{URL}/groups/{id}/roles"))
        .headers(client.requestor.default_headers.clone())
        .send()
        .await;

    #[derive(Clone, Debug, Deserialize)]
    struct Response {
        roles: Vec<GroupRole>,
    }

    let response = client.validate_response(result).await?;
    Ok(client
        .requestor
        .parse_json::<Response>(response)
        .await?
        .roles)
}

pub async fn user_roles(
    client: &mut Client,
    id: u64,
) -> Result<Vec<(GroupInformation, GroupRole)>, Error> {
    let result = client
        .requestor
        .client
        .get(format!("{URL}/users/{id}/groups/roles"))
        .headers(client.requestor.default_headers.clone())
        .send()
        .await;

    #[derive(Clone, Debug, Deserialize)]
    struct GroupAndRole {
        group: GroupInformation,
        role: GroupRole,
    }

    #[derive(Clone, Debug, Deserialize)]
    struct Response {
        #[serde(rename = "data")]
        items: Vec<GroupAndRole>,
    }

    let response = client.validate_response(result).await?;
    let response = client.requestor.parse_json::<Response>(response).await?;

    let mut roles = Vec::new();
    for item in &response.items {
        roles.push((item.group.clone(), item.role.clone()));
    }

    Ok(roles)
}

pub async fn users(client: &mut Client, id: u64, paging: Paging<'_>) -> Result<GroupUsers, Error> {
    let limit = paging.limit.unwrap_or(10).to_string();
    let sort_order = paging.order.unwrap_or_default().to_string();
    let cursor = match paging.cursor {
        Some(cursor) => cursor.to_string(),
        None => String::new(),
    };

    let result = client
        .requestor
        .client
        .get(format!("{URL}/groups/{id}/users"))
        .query(&[
            ("limit", limit),
            ("sortOrder", sort_order),
            ("cursor", cursor),
        ])
        .headers(client.requestor.default_headers.clone())
        .send()
        .await;

    #[derive(Clone, Debug, Deserialize)]
    struct User {
        user: GroupUser,
        role: GroupRole,
    }

    #[derive(Clone, Debug, Deserialize)]
    struct Response {
        #[serde(rename = "data")]
        users: Vec<User>,
        #[serde(rename = "nextPageCursor")]
        next_cursor: Option<String>,
        #[serde(rename = "previousPageCursor")]
        previous_cursor: Option<String>,
    }

    let response = client.validate_response(result).await?;
    let response = client.requestor.parse_json::<Response>(response).await?;

    let mut users = Vec::new();
    for user in response.users {
        users.push((user.user, user.role))
    }

    Ok(GroupUsers {
        users,
        next_cursor: response.next_cursor,
        previous_cursor: response.previous_cursor,
    })
}

pub async fn join(client: &mut Client, id: u64) -> Result<(), Error> {
    #[derive(Serialize)]
    struct Request<'a> {
        #[serde(rename = "sessionId")]
        session_id: &'a str,
        #[serde(rename = "redemptionToken")]
        redemption_token: &'a str,
    }

    let result = client
        .requestor
        .client
        .post(format!("{URL}/groups/{id}/users"))
        .headers(client.requestor.default_headers.clone())
        .json(&Request {
            session_id: "",
            redemption_token: "",
        })
        .send()
        .await;

    client.validate_response(result).await?;
    Ok(())
}

pub async fn remove_join_request(client: &mut Client, id: u64, user_id: u64) -> Result<(), Error> {
    #[derive(Serialize)]
    struct Request {}

    let result = client
        .requestor
        .client
        .delete(format!("{URL}/groups/{id}/join-requests/users/{user_id}"))
        .json(&Request {})
        .headers(client.requestor.default_headers.clone())
        .send()
        .await;

    client.validate_response(result).await?;
    Ok(())
}

pub async fn remove(client: &mut Client, id: u64, user_id: u64) -> Result<(), Error> {
    #[derive(Serialize)]
    struct Request {}

    let result = client
        .requestor
        .client
        .delete(format!("{URL}/groups/{id}/users/{user_id}"))
        .headers(client.requestor.default_headers.clone())
        .json(&Request {})
        .send()
        .await;

    client.validate_response(result).await?;
    Ok(())
}