tcloud-im-api 0.2.1

a rust implement tcloud im api
Documentation
use std::time::Duration;

use serde::{Serialize, Deserialize};

use crate::{client::Client, error::Error};

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct Account {
    pub identifier: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub nick: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub face_url: Option<String>
}


#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct Accounts {
    pub accounts: Vec<String>
}
impl From<Vec<String>> for Accounts {
    fn from(source: Vec<String>) -> Self {
        Self {accounts: source}
    }
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct AccountsResp {
    fail_accounts: Vec<String>
}

#[derive(Debug, Serialize, Deserialize)]
struct UserIdItem {
    #[serde(rename = "UserID")]
    user_id: String
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct DeleteAccounts {
    delete_item: Vec<UserIdItem>
}
impl From<Vec<String>> for DeleteAccounts {
    fn from(source: Vec<String>) -> Self {
        let delete_item = source.into_iter()
            .map(|user_id| UserIdItem{user_id})
            .collect();
        Self {delete_item}
    }
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct DeleteRespItem {
    result_code: u32,
    result_info: String,
    #[serde(rename = "UserID")]
    user_id: String
}

#[derive(Debug, Deserialize)]
pub struct DeleteResp {
    #[serde(rename = "ResultItem")]
    items: Vec<DeleteRespItem>
}

#[derive(Debug, Serialize, Deserialize)]
pub struct CheckUsers {
    #[serde(rename = "CheckItem")]
    user_item: Vec<UserIdItem>
}
impl From<Vec<String>> for CheckUsers {
    fn from(source: Vec<String>) -> Self {
        let user_item = source.into_iter()
            .map(|user_id| UserIdItem{user_id})
            .collect();
        Self {user_item}
    }
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct CheckRespItem {
    result_code: u32,
    result_info: String,
    #[serde(rename = "UserID")]
    user_id: String,
    account_status: String
}

#[derive(Debug, Deserialize)]
pub struct CheckResp {
    #[serde(rename = "ResultItem")]
    items: Vec<CheckRespItem>
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct Kick {
    identifier: String  
}

impl From<String> for Kick {
    fn from(source: String) -> Self {
        Kick {identifier: source}
    }
}

#[derive(Debug, Serialize, Deserialize)]
pub struct OnlineStatus {
    #[serde(rename = "IsNeedDetail")]
    need_detail: u32,
    #[serde(rename = "To_Account")]
    to_account: Vec<String>
}

impl OnlineStatus {
    pub fn new(need_detail: bool, accounts: Vec<String>) -> Self {
        Self {need_detail: if need_detail {1} else {0}, to_account: accounts}
    }
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct OnlineDetail {
    platform: String,
    status: String
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct OnlineState {
    #[serde(rename = "To_Account")]
    account: String,
    status: String,
    detail: Option<OnlineDetail>
}

#[derive(Debug, Deserialize)]
pub struct QueryError {
    #[serde(rename = "To_Account")]
    account: String,
    #[serde(rename = "ErrorCode")]
    code: u32
}

#[derive(Debug, Deserialize)]
pub struct QueryResp {
    #[serde(rename = "QueryResult")]
    result: Vec<OnlineState>,
    #[serde(rename = "ErrorList")]
    errors: Vec<QueryError>
}

pub struct AccountApi<'a> {
    inner: &'a Client
}

impl<'a> AccountApi<'a> {
    define_api!(import, "/v4/im_open_login_svc/account_import", Account, ());
    define_api!(multi_import, "/v4/im_open_login_svc/multiaccount_import",Accounts, AccountsResp);
    define_api!(delete, "/v4/im_open_login_svc/account_delete", DeleteAccounts, DeleteResp);
    define_api!(check, "/v4/im_open_login_svc/account_check", CheckUsers, CheckResp);
    define_api!(kick, "/v4/im_open_login_svc/kick", Kick, ());
    define_api!(query_online_status, "/v4/openim/query_online_status", OnlineStatus, QueryResp);

    pub fn gen_sign(&self, user_id: &str, expire: Duration) -> Result<String, Error> {
        super::usersig::gen_usersig(
            self.inner.sdkappid, 
            self.inner.key.as_str(),
            user_id, 
            expire
        )
    }

    pub fn new(client: &'a Client) -> Self {
        AccountApi{inner: client}
    }
}