use crate::RoliError;
use crate::{Client, Code};
use reqwest::header;
use serde::{Deserialize, Serialize};
const GROUP_SEARCH_URL: &str = "https://www.rolimons.com/groupapi/search?searchstring=";
#[derive(Serialize, Deserialize)]
struct GroupSearchResponse {
success: bool,
result_count: i64,
groups: Vec<Vec<Code>>,
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Serialize, Deserialize)]
pub struct GroupSearchResult {
pub id: u64,
pub name: String,
pub member_count: u64,
pub thumbnail_url: String,
}
impl GroupSearchResult {
fn from_raw(codes: Vec<Code>) -> Result<Self, RoliError> {
if codes.len() != 7 {
return Err(RoliError::MalformedResponse);
}
let id = codes[0].to_i64()? as u64;
let name = codes[1].to_string();
let member_count = codes[5].to_i64()? as u64;
let thumbnail_url = codes[6].to_string();
Ok(Self {
id,
name,
member_count,
thumbnail_url,
})
}
}
impl Client {
pub async fn group_search(
&self,
group_name: &str,
) -> Result<Vec<GroupSearchResult>, RoliError> {
let formatted_url = format!("{}{}", GROUP_SEARCH_URL, group_name);
let request_result = self
.reqwest_client
.get(formatted_url)
.header(header::USER_AGENT, crate::USER_AGENT)
.send()
.await;
match request_result {
Ok(response) => {
let status_code = response.status().as_u16();
match status_code {
200 => {
let raw = match response.json::<GroupSearchResponse>().await {
Ok(x) => x,
Err(_) => return Err(RoliError::MalformedResponse),
};
if !raw.success {
return Err(RoliError::RequestReturnedUnsuccessful);
}
let mut search_outputs = Vec::new();
for group in raw.groups {
search_outputs.push(GroupSearchResult::from_raw(group)?);
}
Ok(search_outputs)
}
429 => Err(RoliError::TooManyRequests),
500 => Err(RoliError::InternalServerError),
_ => Err(RoliError::UnidentifiedStatusCode(status_code)),
}
}
Err(e) => Err(RoliError::ReqwestError(e)),
}
}
}