use serde::{Deserialize, Serialize};
use std::str::FromStr;
use qstring::QString;
use strum::EnumString;
use crate::command::CommandError;
use super::*;
use crate::data::player::PlayerId;
id_type! {
pub struct GroupId(pub i64);
}
#[derive(Serialize, Deserialize, EnumString, strum::Display, Debug, Clone, Copy, PartialEq, Eq)]
#[serde(into = "String", try_from = "String")]
#[strum(serialize_all = "lowercase")]
pub enum GroupRole {
Leader,
Member,
}
impl_enum_string_conversions!(GroupRole);
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct GroupPlayer {
pub name: String,
#[serde(rename = "pid")]
pub player_id: PlayerId,
pub role: GroupRole,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct GroupInfo {
pub name: String,
#[serde(rename = "gid")]
pub group_id: GroupId,
pub players: Vec<GroupPlayer>,
}
impl_try_from_response_payload!(GroupInfo);
impl_try_from_response_payload!(Vec<GroupInfo>);
impl GroupInfo {
pub fn leader(&self) -> &GroupPlayer {
for player in &self.players {
if player.role == GroupRole::Leader {
return player
}
}
panic!("every group should have a leader")
}
pub fn player(&self, player_id: PlayerId) -> Option<&GroupPlayer> {
for player in &self.players {
if player.player_id == player_id {
return Some(player)
}
}
None
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(untagged)]
pub enum SetGroupResult {
Deleted,
CreatedOrModified {
#[serde(rename = "gid")]
group_id: GroupId,
name: String,
}
}
impl_try_from_response_qs!(SetGroupResult);
impl TryFrom<QString> for SetGroupResult {
type Error = CommandError;
fn try_from(qs: QString) -> Result<Self, Self::Error> {
let group_id = match qs.get("gid") {
Some(gid_str) => {
gid_str.parse::<GroupId>()
.map_err(|err| CommandError::MalformedResponse(format!("could not parse 'gid': {err:?}")))?
},
None => return Ok(Self::Deleted),
};
let name = match qs.get("name") {
Some(name) => name.to_string(),
None => return Ok(Self::Deleted),
};
Ok(Self::CreatedOrModified {
group_id,
name,
})
}
}