use anyhow::{bail, Error};
use serde::Deserialize;
use serde_json::Value;
use crate::User;
#[derive(Debug)]
pub enum Event {
Gift(Gift),
Comment(Comment),
Like(Like),
Share(Share),
Follow(Follow),
Task(Task),
Unknown(Value, Error),
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Gift {
pub user: User,
pub gift_id: String,
pub gift_name: String,
pub gift_total_dou: u32,
pub count: u32,
}
#[derive(Deserialize, Debug)]
pub struct Comment {
pub user: User,
pub content: String,
}
#[derive(Deserialize, Debug)]
pub struct Like {
pub user: User,
pub count: u32,
}
#[derive(Deserialize, Debug)]
pub struct Share {
pub user: User,
}
#[derive(Deserialize, Debug)]
pub struct Follow {
pub user: User,
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Task {
pub user: Option<User>,
pub task_id: u32,
}
impl From<&Value> for Event {
fn from(value: &Value) -> Self {
match parse(value) {
Ok(e) => e,
Err(e) => Event::Unknown(value.clone(), e),
}
}
}
fn parse(value: &Value) -> anyhow::Result<Event> {
let cmd = value.get("cmd").and_then(|t| t.as_u64()).unwrap_or(0);
let payload = value.get("payload").unwrap_or(&Value::Null);
match cmd {
2 => Ok(Event::Gift(serde_json::from_value(payload.clone())?)),
3 => Ok(Event::Comment(serde_json::from_value(payload.clone())?)),
5 => Ok(Event::Task(serde_json::from_value(payload.clone())?)),
7 => Ok(Event::Like(serde_json::from_value(payload.clone())?)),
9 => Ok(Event::Share(serde_json::from_value(payload.clone())?)),
10 => Ok(Event::Follow(serde_json::from_value(payload.clone())?)),
_ => bail!("cmd unsupport"),
}
}